Diseño sobre FPGA de una Unidad Aritmética...

99
Diseño sobre FPGA de una Unidad Aritmética Decimal TITULACIÓN: Ingeniería Técnica Industrial en Electrónica Industrial AUTOR: Alejandro Baena Alonso DIRECTOR: Jean-Pierre Deschamps FECHA: Febrero / 2010

Transcript of Diseño sobre FPGA de una Unidad Aritmética...

Page 1: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal

TITULACIÓN: Ingeniería Técnica Industrial en Electrónica Industrial

AUTOR: Alejandro Baena Alonso

DIRECTOR: Jean-Pierre Deschamps

FECHA: Febrero / 2010

Page 2: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal

1. ÍNDICE GENERAL

Page 3: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Índice general

- 3 -

2. INTRODUCCIÓN

2.1 Objetivos del proyecto ............................................................................................................... 7 2.2 Aspectos básicos ......................................................................................................................... 7

2.2.1 Aritmética decimal.............................................................................................................. 7 2.2.2 Código decimal codificado en binario (BCD) .................................................................... 8 2.2.3 Dispositivos programables.................................................................................................. 8

2.3 Diseño de Sistemas Electrónicos ............................................................................................... 9 2.3.1 Tendencias generales en Diseño Electrónico...................................................................... 9 2.3.2 Lenguajes de descripción del hardware .............................................................................. 9

2.3.2.1 ¿Qué son los lenguajes de descripción del hardware?............................................. 9 2.3.2.2 El lenguaje VHDL ................................................................................................... 10

2.3.2.2.1 Introducción al lenguaje VHDL .................................................................... 10 2.3.2.2.2 Características............................................................................................... 10 2.3.2.2.3 Niveles de descripción ................................................................................... 11 2.3.2.2.4 Estructura de una descripción....................................................................... 11 2.3.2.2.5 Metodología de diseño................................................................................... 12

2.3.3 Dispositivos lógicos programables ................................................................................... 13 2.3.4 Componentes IP (IP cores)............................................................................................... 15 2.3.5 Prototipado rápido ............................................................................................................ 16

2.4 Spartan-3E Starter Kit Board ................................................................................................... 16 3. MEMORIA DESCRIPTIVA

3.1 La Unidad Aritmética Decimal ............................................................................................... 20 3.2 Bloques de la unidad ................................................................................................................ 21

3.2.1 Sumador/Restador............................................................................................................. 21 3.2.1.1 Sumador .................................................................................................................. 21

3.2.1.1.1 Sumador de 1 dígito BCD (bloque “one_digit_adder.vhd”)......................... 21 3.2.1.1.2 Sumador de n dígitos decimales .................................................................... 24

3.2.1.2 Restador…............................................................................................................... 26 3.2.1.2.1 Cálculo del complemento a 9 (bloque “nine_complement.vhd”).................. 27 3.2.1.2.2 Sumador/Restador en complemento a 10n ..................................................... 28

3.2.1.3 Sumador/Restador, representación con signo y magnitud (bloque “n_adder_subs.vhd”).......................................................................................................... 29

3.2.2 Multiplicador…….. .......................................................................................................... 32 3.2.2.1 Multiplicador de 1x1 dígitos BCD (bloque “one_digit_multiplier.vhd”)................ 32 3.2.2.2 Multiplicador de Nx1 dígitos BCD (bloque“n_by_one_multiplier.vhd”)............... 34 3.2.2.3 Multiplicador de NxM dígitos BCD (bloque“n_by_m_multiplier.vhd”) ................ 37

3.2.3 Divisor .............................................................................................................................. 41 3.2.3.1 Algoritmo de división binaria ................................................................................. 41 3.2.3.2 Algoritmo de división BCD ..................................................................................... 42 3.2.3.3 Error generado........................................................................................................ 42 3.2.3.4 Divisor BCD (bloque “divider.vhd”)...................................................................... 43

3.3 Diseño de la Unidad Aritmética Decimal ............................................................................... 48

Page 4: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Índice general

- 4 -

4. MEMORIA EXPERIMENTAL

4.1 Descripción del proceso ........................................................................................................... 54 4.2 Especificaciones ........................................................................................................................ 54 4.3 Elementos necesarios................................................................................................................ 55 4.4 Arquitectura a desarrollar ...................................................................................................... 55 4.5 Módulos IP de terceros utilizados........................................................................................... 57

4.5.1 Microcontrolador PicoBlaze (módulo “kcpsm.vhd”)........................................................ 57 4.5.2 Interfaz LCD (módulo “lcd_interface.vhd”)..................................................................... 58

4.6 Memoria de programa (módulo “program_memory.vhd”) ................................................... 60 4.7 Generación del circuito (módulo “main.vhd”) ....................................................................... 62 4.8 Asignación de pines en la FPGA (archivo “pins.ucf”) .......................................................... 63 4.9 Implementación en la FPGA ................................................................................................... 65

4.9.1 Generación del archivo ..................................................................................................... 66 4.9.2 Implementación en la FPGA ............................................................................................ 68

5. ANEXOS

5.1 Modelos VHDL......................................................................................................................... 72 5.1.1 Sumador de 1 dígito BCD (one_digit_adder.vhd)............................................................ 72 5.1.2 Complemento a 9 (nine_complement.vhd) ....................................................................... 73 5.1.3 Sumador/Restador de n dígitos decimales (n_adder_subs.vhd) ....................................... 73 5.1.4 Multiplicador de 1x1 dígitos BCD (one_digit_multiplier.vhd) ........................................ 75 5.1.5 Multiplicador de Nx1 dígitos BCD (n_by_one_multiplier.vhd) ....................................... 76 5.1.6 Multiplicador de NxM dígitos BCD (n_by_m_multiplier.vhd)......................................... 78 5.1.7 Divisor BCD (divider.vhd) ............................................................................................... 80 5.1.8 Unidad Aritmética Decimal (arithmetic_unit.vhd) ........................................................... 83 5.1.9 Memoria de programa (program_memory.vhd) ............................................................... 86 5.1.10 Circuito completo (main.vhd) ......................................................................................... 89

5.2 Programa en lenguaje ensamblador (decimal_unit.asm) ...................................................... 94 5.3 Asignación de pines en la Spartan-3E (pins.ucf) .................................................................... 97 6. BIBLIOGRAFÍA........................................................................................................................ 99

Page 5: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal

2. INTRODUCCIÓN

Page 6: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 6 -

2.1 Objetivos del proyecto ............................................................................................................... 7

2.2 Aspectos básicos ......................................................................................................................... 7

2.2.1 Aritmética decimal.............................................................................................................. 7

2.2.2 Código decimal codificado en binario (BCD) .................................................................... 8

2.2.3 Dispositivos programables.................................................................................................. 8

2.3 Diseño de Sistemas Electrónicos ............................................................................................... 9

2.3.1 Tendencias generales en Diseño Electrónico...................................................................... 9

2.3.2 Lenguajes de descripción del hardware .............................................................................. 9

2.3.2.1 ¿Qué son los lenguajes de descripción del hardware?............................................. 9

2.3.2.2 El lenguaje VHDL ................................................................................................... 10

2.3.2.2.1 Introducción al lenguaje VHDL .................................................................... 10

2.3.2.2.2 Características............................................................................................... 10

2.3.2.2.3 Niveles de descripción ................................................................................... 11

2.3.2.2.4 Estructura de una descripción....................................................................... 11

2.3.2.2.5 Metodología de diseño................................................................................... 12

2.3.3 Dispositivos lógicos programables ................................................................................... 13

2.3.4 Componentes IP (IP cores)............................................................................................... 15

2.3.5 Prototipado rápido ............................................................................................................ 16

2.4 Spartan-3E Starter Kit Board ................................................................................................... 16

Page 7: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 7 -

2.1 Objetivos del proyecto El objetivo de este proyecto es el diseño del modelo VHDL de una Unidad Aritmética Decimal, que pueda funcionar como coprocesador/acelerador dentro de otro sistema más complejo. Por tanto, se trata de un componente virtual utilizable en cualquier tipo de sistemas que requieran operar en decimal. Dicha unidad permitirá realizar las operaciones aritméticas básicas – siempre operando en decimal – como son la suma, resta, multiplicación y división de dos valores decimales. Posteriormente, y a modo de testeo del modelo resultante, se implementará sobre una FPGA, la SPARTAN-3E modelo XC3S500E de XILINX. Para la creación y simulación de la unidad aritmética decimal se ha utilizado el programa MODELSIM PE en su versión STUDENT EDITION. Para la implementación en la FPGA, se ha utilizado el ensamblador PBLAZ IDE para la creación de la memoria de programa, y el paquete ISE DESIGN SUITE de XILINX para la síntesis y grabación del código en la placa de pruebas. 2.2 Aspectos básicos 2.2.1 Aritmética decimal Los sistemas que operan en decimal son preferibles a los que lo hacen en binario en un gran número de aplicaciones aritméticas informáticas. El motivo principal no es la complejidad de las interfaces de codificación y decodificación (que también influye), sino principalmente la falta de precisión y claridad de los resultados. La aritmética decimal desempeña un papel clave en el procesamiento de datos en diversos entornos, ya sean comerciales, financieros o de aplicaciones basadas en Internet, entre otros. Y las prestaciones que estos requieren no quedan satisfechas con las unidades convencionales que internamente operan en binario. En consecuencia, los procesadores de propósito general que incluyen la implementación hardware de aritmética decimal están adquiriendo relevancia Actualmente, el sistema decimal codificado en binario (BCD) es utilizado en el diseño de algoritmos de aritmética decimal; aunque otros sistemas de codificación podrían resultar interesantes, el sistema BCD parece la mejor opción por el momento.

Page 8: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 8 -

2.2.2 Código decimal codificado en binario (BCD) El código decimal codificado en binario (BCD, Binary Coded Decimal, también conocido como código 8421) codifica los dígitos decimales del 0 al 9 mediante sus representaciones binarias sin signo de 4 bits, desde 0000 a 1001. Las palabras de código restantes, de 1010 a 1111, no se utilizan. Las conversiones entre las representaciones BCD y decimal son triviales e implican la sustitución directa de cuatro bits por cada dígito decimal. El decimal codificado en binario es un código ponderado, puesto que cada dígito decimal puede obtenerse a partir de su palabra de código asignando un peso fijo a cada bit de palabra de código. Los pesos para los bits BCD son 8, 4, 2, 1, y por esta razón el código se denomina en ocasiones código 8421. En la siguiente tabla se representa la correspondencia entre los números decimales y las combinaciones binarias del código BCD:

Decimal BCD 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001

Tabla 2.1. Correspondencia entre los dígitos decimales y código BCD

2.2.3 Dispositivos programables Hoy en día, las FPGA (Field Programmable Gate Arrays, de las que se hablará más adelante) son una de las tecnologías disponibles para el desarrollo de sistemas electrónicos. Representan una atractiva opción para la producción de pequeñas cantidades ya que sus costes fijos (coste del prototipo, de la primera unidad) son bastante más bajos que los correspondientes en ASIC (Application-Specific Integrated Circuit, circuitos integrados de aplicación específica). Además, en pos de reducir el tamaño y por tanto el coste unitario, una posibilidad interesante es reconfigurarlas mientras operan de modo que el mismo dispositivo pueda ejecutar diferentes funciones predefinidas.

Page 9: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 9 -

2.3 Diseño de Sistemas Electrónicos 2.3.1 Tendencias generales en Diseño Electrónico Actualmente los sistemas electrónicos están muy presentes en la mayoría de ámbitos, desde la electrónica de consumo a los sistemas de control industrial, pasando por las aplicaciones para automoción o seguridad, y un largo etcétera… El problema principal radica en la complejidad del diseño de muchos de los elementos, donde se exige, por ejemplo, que sean de fácil utilización y adaptables a varias aplicaciones, que consuman pocos recursos y que puedan estar rápidamente a la venta… La tecnología actual de circuitos integrados permite realizar e integrar estos complejos sistemas en muy poco espacio; son los llamados sistemas empotrados (o embebidos) o SoC (System on Chip). Estos sistemas, como pueden ser los ASIC (Application-Specific Integrated Circuit) o las FPGA, permiten integrar en el mismo dispositivo uno o más microprocesadores o microcontroladores, coprocesadores, diversos bloques de memoria de diferentes tipos, periféricos de entrada-salida, osciladores, buses para interconectar los bloques, etc. Estos sistemas embebidos para aplicaciones específicas incluyen hardware y software específico. En el caso de las FPGA, al ser dispositivos reconfigurables, son altamente útiles para el desarrollo de prototipos o pequeñas cantidades, a un precio razonablemente bajo. 2.3.2 Lenguajes de descripción del hardware 2.3.2.1 ¿Qué son los lenguajes de descripción del hardware? Los lenguajes de descripción hardware (HDL, Hardware Description Language) surgen de la necesidad de los diseñadores de disponer de un conjunto de herramientas que permitan describir los sistemas digitales de formas diferentes, facilitando el diálogo entre los propios diseñadores, aunque también entre las herramientas de diseño asistido por ordenador (CAD, Computer-Aided Design) y entre diseñadores y herramientas. Los sistemas de desarrollo basados en lenguajes HDL permiten especificar y modelar la estructura y función de un circuito digital; incluyen herramientas para compilar, simular y sintetizar sistemas digitales. Estas herramientas de programación se utilizan para comprobar el funcionamiento del modelo antes de que sea construido. Actualmente, los lenguajes HDL más utilizados son VHDL y Verilog, ya que están estandarizados por el IEEE (Institute of Electrical and Electronic Engineers). Nosotros nos centraremos en el primero de ellos.

Page 10: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 10 -

2.3.2.2 El lenguaje VHDL 2.3.2.2.1 Introducción al lenguaje VHDL VHDL proviene de VHSIC (Very High Speed Integrated Circuit) Hardware Description Language. VHDL es un lenguaje de descripción del hardware que puede utilizarse para modelar, documentar, simular, verificar y sintetizar un sistema digital. Por tanto, abarca el ciclo completo de diseño (salvo el trazado físico o layout) desde las especificaciones iniciales hasta la construcción del prototipo hardware. Proporciona el soporte necesario para especificar su comportamiento o estructura, incluyendo jerarquías. Asimismo, es útil para metodologías de diseño ascendentes (bottom-up) como, sobre todo, descendentes (top-down). La semántica y construcciones del lenguaje permiten también diseñar con facilidad bancos de prueba (test-benches), mediante los que se lleva a cabo la simulación de los sistemas modelados. 2.3.2.2.2 Características VDHL es un lenguaje de descripción hardware de ámbito general derivado del lenguaje de alto nivel ADA (que es el lenguaje para programar sistemas en tiempo real por excelencia). Dispone de tipos abstractos para definir el formato y valores de señales, variables, constantes, etc., y proporciona amplias facilidades para la realización de algoritmos. Admite casi todos los niveles de descripción, desde el algorítmico (nivel más alto) hasta el lógico (nivel más bajo). Para ello proporciona herramientas semánticas y sintácticas que se pueden agrupar así:

• Aquellas orientadas a las descripciones del comportamiento del circuito. • Aquellas orientas a la descripción de las relaciones entre los distintos bloques

de un circuito, es decir, su estructura. Al realizar una descripción VHDL es importante elegir adecuadamente el nivel de función del objetivo perseguido. Por ejemplo, si se pretende sintetizar la descripción realizada, es decir, si el objetivo final es obtener un conjunto de puertas e interconexiones, no se debe emplear el nivel algorítmico, pues en general las herramientas actuales de síntesis no procesan de forma eficiente estas descripciones. Sin embargo, este nivel sí es adecuado cuando el objetivo es comprobar que un sistema complejo funciona correctamente, pues se puede describir y simular de una forma rápida y eficaz.

Page 11: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 11 -

2.3.2.2.3 Niveles de descripción El lenguaje VHDL presenta tres métodos básicos para describir un circuito digital por software:

• El nivel algorítmico es el que presenta un mayor grado de abstracción (alto nivel). Aquí el diseñador solo describe el comportamiento del sistema, sin preocuparse de las señales o componentes internos del mismo. También llamado nivel de comportamiento o behavior.

• El nivel RTL (Register-Transfer Level, nivel de transferencia de registros)

proporciona un cierto grado de abstracción con respecto al hardware, pero el diseñador se ve obligado a describir las distintas señales que interactúan en un circuito y su comportamiento en función de las entradas por medio de ecuaciones lógicas y sentencias de asignación. También conocido como nivel de flujo de datos.

• El nivel lógico describe la estructura interna de un circuito basándose en unos

componentes básicos definidos previamente (equivaldría a un diagrama lógico). 2.3.2.2.4 Estructura de una descripción Toda descripción en VHDL está constituida al menos por tres tipos de elementos: bibliotecas (libraries), entidades (entities) y arquitecturas (architectures). El diseñador generalmente realiza la descripción de las entidades empleando elementos almacenados en las bibliotecas. En la declaración de la entidad se define el diseño como si fuera un producto encapsulado, indicando el número de pines, los puertos de entrada y salida. La entidad puede definir bien las entradas y salidas de un circuito integrado por diseñar o puede definir la interfaz de un módulo que será utilizado en un diseño más grande. Para que la descripción de un circuito sea completa se necesita, además de su declaración como entidad, una especificación de su funcionamiento. La arquitectura es la encargada de ello. Es posible realizar diversas descripciones del funcionamiento del circuito, por lo que pueden existir varias arquitecturas para una misma entidad.

Page 12: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 12 -

2.3.2.2.5 Metodología de diseño La Figura 2.1 muestra el flujo de diseño de un circuito en VHDL, desde su concepción hasta su fabricación.

Figura 2.1. Flujo de diseño en VHDL Una vez finalizada la prueba del concepto, se pasa al diseño detallado. Dependiendo de la herramienta de síntesis que se utilice y de las especificaciones del circuito, la descripción VHDL estará desarrollada en un nivel de abstracción mayor o menor (desde un nivel algorítmico a uno lógico). Por último se aborda la síntesis del circuito, es decir, el paso de una descripción en VHDL a un circuito real. El proceso de diseño puede terminar antes si el objetivo final no es la fabricación sino, por ejemplo, la creación de componentes de biblioteca para uso posterior.

Page 13: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 13 -

2.3.3 Dispositivos lógicos programables Existen dos grandes grupos de dispositivos lógicos programables: PLDs (Programmable Logic Device, dispositivo lógico programable) y FPGAs (Field Programmable Gate Array, matriz de puertas configurables).

Figura 2.2. Tipos de lógica programable Los PLDs están basados en una matriz AND + OR. Dentro de los PLDs encontramos las PROM (Programmable Read Only Memory), las PAL (Programmable Logic Array) y las PAL (Programmable Array Logic).

Figura 2.3. Familia de los PLD Dentro de las PAL se encuentran los CPLDs (Complex PLD), compuestos por la integración de PLDs (PAL/GAL o PLA). Están formados por bloques lógicos y matrices de interruptores, donde cada bloque lógico corresponde a un PLD.

Figura 2.4. Ejemplo de arquitectura de CPLD (con 4 elementos lógicos o bloques programables)

Page 14: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 14 -

Las FPGA están compuestas por una matriz de elementos lógicos cuya interconexión y funcionalidad se puede programar. En comparación con los dispositivos CPLD, difieren en la arquitectura, no utilizan matrices de tipo PAL/PLA y tienen unas densidades mucho mayores que los anteriores. Una FPGA típica tiene un número de puertas equivalentes mucho mayor que un dispositivo CPLD típico. Los elementos que implementan las funciones lógicas en las FPGA son, generalmente, mucho más pequeños que en los CPLD, por lo que hay muchos más de esos elementos. Asimismo, en las FPGA, las interconexiones programables están organizadas según una disposición de filas y columnas.

Figura 2.5. Arquitectura interna de una FPGA Los tres elementos básicos en una FPGA son el bloque configurable (CLB, Configurable Logic Block), las interconexiones y los bloques de entrada/salida (E/S). Los bloques CLB de una FPGA son menos complejos que sus homónimos en un CPLD, pero suele haber muchos más de ellos. La matriz distribuida de interconexiones programables permite interconectar los bloques CLB entre sí y conectarlos a las entradas y a las salidas. Los bloques de E/S situados alrededor del perímetro de las estructura proporcionan un acceso de entrada/salida o bidireccional, individualmente seleccionable, hacia el mundo exterior. Estructura de los bloques lógicos configurables Cada bloque lógico de la FPGA está formado por múltiples módulos lógicos más pequeños (que son los componentes básicos) y por una serie de interconexiones programables locales que se emplean para conectar entre sí los módulos lógicos que componen el CLB.

Módulo lógico

Módulo lógico

Módulo lógico

CLB

Interconexión local

Figura 2.6. Arquitectura de un CLB

Page 15: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 15 -

Un módulo lógico puede configurarse para implementar lógica combinacional, lógica registrada o una combinación de ambas. Se emplea un flip-flop que forma parte de la lógica asociada para implementar lógica registrada. A continuación se muestra un diagrama de bloques de un módulo lógico típico basado en LUT (Look-Up Table, tipo de memoria programable que se utiliza para generar funciones booleanas):

LUT Lógica asociada

A0

A1

An-1

Salida suma de productos

Módulo lógico

E/S…

Figura 2.7. Diagrama de bloques básico de un módulo lógico Los dispositivos FPGA son reprogramables, y los de gran tamaño pueden tener decenas de miles de bloques CLB, además de memoria y otros recursos. Por todo ello y la gran flexibilidad que presentan, son ideales para realizar prototipos de manera rápida, en pequeñas cantidades. 2.3.4 Componentes IP (IP cores) Dentro de una FPGA se puede incluir la funcionalidad de varios circuitos integrados. Esta funcionalidad puede ser desarrollada uno mismo o adquirida a través de terceros. Debido a que estas funcionalidades son como componentes electrónicos, pero sin su parte física, se les suele llamar componentes virtuales. En la industria se les conoce como bloques de propiedad intelectual o IP cores (Intellectual Property). Existen tres tipos de IP cores:

• Hablamos de soft-core cuando se trata de código sintetizable, similar al código fuente para software o también a descripción a nivel de puerta (netlist).

• Entendemos por hard-core el caso de una descripción física, a nivel físico (de transistores); estos módulos presentan problemas a la hora de asociar diferentes procesos entre ellos o pasar de una línea de fabricación a otra.

• Por firm-core nos referimos a un diseño que puede ser modificado en términos de placement & routing o en tecnología de bibliotecas.

Los dispositivos FPGA que contienen procesadores integrados y otras funciones implementadas en forma de módulos de hardware (hard-core) y de módulos de software (soft-core) se conocen con el nombre de dispositivos FPGA de plataforma, porque pueden emplearse para implementar un sistema completo sin necesidad de dispositivos externos de soporte. El objetivo de este proyecto es el de crear un IP core o componente IP que realice operaciones en decimal. En este caso se tratará de un soft-core.

Page 16: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 16 -

2.3.5 Prototipado rápido Un sistema completo (hardware y software) y su entorno no puede ser validado únicamente mediante la simulación. El objetivo es comprobar en la práctica el funcionamiento del prototipo a un coste asequible. El prototipado rápido es una posibilidad que facilita enormemente el diseño, mediante la cual un circuito compuesto por una gran cantidad de puertas lógicas puede ser implementado en un circuito integrado configurable, como lo puede ser una FPGA, a partir de una descripción en HDL mediante un simple ordenador personal (PC), sin la necesidad de adquirir o disponer de un equipamiento caro. Y la tecnología que permite dicha técnica la forman las tarjetas de prototipado rápido, que permiten reproducir desde funciones sencillas hasta complejos sistemas en un chip (SoC, System on Chip). Dichas tarjetas incluyen los componentes necesarios para esta misión: dispositivos programables (CPLD, FPGA), memoria de datos y de programa, componentes de entrada-salida y conectores (displays, puertos Ethernet, USB, RS-232, conversores analógico-digital y viceversa, interruptores, LEDs…), osciladores internos (reloj del sistema)… Un ejemplo de este tipo de dispositivos es la Spartan-3E Starter Kit Board, que utilizaremos para comprobar el funcionamiento de nuestra Unidad Aritmética Decimal. 2.4 Spartan-3E Starter Kit Board La unidad Spartan-3E Starter Kit Board nos proporciona las herramientas necesarias para testear nuestro sistema. Incluye la placa de pruebas con una FPGA Spartan-3E modelo XC3S500E, fuente de alimentación, cable USB para programar el dispositivo, software para sintetizar e implementar nuestro modelo y manuales de referencia. A continuación enumeramos algunas características de la placa:

• Dispositivos Xilinx integrados:

- FPGA de la familia Spartan-3E modelo XC3S500E-4FG320C (con 232 pines de E/S para el usuario, 1164 CLBs o bloque lógicos configurables y 10000 celdas o módulos lógicos)

- Controlador CPLD CoolRunner-II CPLD (XC2C64A-5VQ44C) - 4 Mbits de memoria PROM Platform Flash

• Reloj: oscilador de 50 MHz • Otra memoria incluida:

- 128 Mbits de memoria Parallel Flash - 16 Mbits de memoria SPI (Serial Peripheral Interface) Flash - 64 MBytes de memoria DDR SDRAM

Page 17: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Introducción

- 17 -

• Interfaces y conectores:

- 4 interruptores tipo pulsador - 4 salidas DAC (Digital-to-Analog Converter) - 2 entradas ADC (Analog-to-Digital Converter) - Conexión Ethernet 10/100 - Puerto USB - 2 puertos serie RS-232 - Puerto PS/2 para ratón o teclado - 4 interruptores tipo slide - …

• Display: Pantalla LCD de 2 líneas de 16 caracteres cada una

Figura 2.8. Vista superior de la Spartan-3E

Page 18: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal

3. MEMORIA DESCRIPTIVA

Page 19: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 19 -

3.1 La Unidad Aritmética Decimal ............................................................................................... 20

3.2 Bloques de la unidad ................................................................................................................ 21

3.2.1 Sumador/Restador............................................................................................................. 21

3.2.1.1 Sumador .................................................................................................................. 21

3.2.1.1.1 Sumador de 1 dígito BCD (bloque “one_digit_adder.vhd”)......................... 21

3.2.1.1.2 Sumador de n dígitos decimales .................................................................... 24

3.2.1.2 Restador…............................................................................................................... 26

3.2.1.2.1 Cálculo del complemento a 9 (bloque “nine_complement.vhd”).................. 27

3.2.1.2.2 Sumador/Restador en complemento a 10n ..................................................... 28

3.2.1.3 Sumador/Restador, representación con signo y magnitud (bloque “n_adder_subs.vhd”).......................................................................................................... 29

3.2.2 Multiplicador…….. .......................................................................................................... 32

3.2.2.1 Multiplicador de 1x1 dígitos BCD (bloque “one_digit_multiplier.vhd”)................ 32

3.2.2.2 Multiplicador de Nx1 dígitos BCD (bloque“n_by_one_multiplier.vhd”)............... 34

3.2.2.3 Multiplicador de NxM dígitos BCD (bloque“n_by_m_multiplier.vhd”) ................ 37

3.2.3 Divisor .............................................................................................................................. 41

3.2.3.1 Algoritmo de división binaria ................................................................................. 41

3.2.3.2 Algoritmo de división BCD ..................................................................................... 42

3.2.3.3 Error generado........................................................................................................ 42

3.2.3.4 Divisor BCD (bloque “divider.vhd”)...................................................................... 43

3.3 Diseño de la Unidad Aritmética Decimal ............................................................................... 48

Page 20: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 20 -

3.1 La Unidad Aritmética Decimal Nuestro objetivo es la creación del modelo VHDL de una Unidad Aritmética Decimal, es decir, una unidad que, operando en sistema BCD, realice las operaciones de suma, resta, multiplicación y división.

Figura 3.1. Representación previa de la Unidad Aritmética Decimal Necesitaremos un sistema que dados dos valores de entrada de n dígitos BCD cada uno, x e y, calcule el resultado z (de 2n dígitos BCD) de la operación que hayamos escogido previamente mediante la señal de entrada operation. Además, contaremos con las señales de entrada start (para iniciar el cálculo interno cuando sea necesario), reset (reiniciar el sistema), clk (señal de reloj) y las de salida carry (acarreo de salida cuando sea necesario) y done (indicador de resultado disponible). Para ello, la primera idea es que deberemos crear el modelo necesario para poder ejecutar cada operación.

Unidad aritmética decimal

Sumador Restador Multiplicador Divisor

Figura 3.2. Estructura interna previa de la Unidad Aritmética Decimal Por consiguiente, nos centraremos primero en el diseño de los módulos primarios que realizarán las diferentes operaciones y después los integraremos en la unidad principal.

Page 21: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 21 -

3.2 Bloques de la unidad 3.2.1 Sumador/Restador 3.2.1.1 Sumador En este apartado nuestro objetivo es la realización de un sumador de n dígitos decimales. Para ello, lo primero que hacemos es crear una estructura básica, el sumador de 1 dígito decimal. 3.2.1.1.1 Sumador de 1 dígito BCD (bloque “one_digit_adder.vhd”) La idea principal de este bloque es que, dadas dos entradas, a y b, que representan cada una 1 dígito decimal, tenemos una arquitectura cuya misión es realizar la suma de ambos dígitos y dar como resultado (c) 1 dígito decimal de salida y un acarreo (carry_out) en caso de ser necesario.

Figura 3.3. Sumador de 1 dígito decimal La estructura interna del bloque sería la siguiente:

Figura 3.4. Arquitectura del sumador de 1 dígito decimal

Page 22: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 22 -

Tenemos dos entradas, a y b, que pueden representar cualquier dígito decimal del 0 al 9, una salida c que también será un dígito BCD, y un acarreo de salida (carry_out). También hay un acarreo de entrada, carry_in, que nos permitirá interconectar diversos bloques. Funcionamiento Al realizar la suma binaria se nos pueden presentar dos casos: si el resultado de dicha suma es igual o menor a 9 (‘1001’), el resultado es directo (es decir, a + b = c). Si la suma es superior a 9, debemos realizar una corrección al valor obtenido. El proceso en este segundo caso es el siguiente: realizamos la suma de a y b en binario, obteniendo el valor intermedio d formado por 5 bits (Figura 3.4). Son 5 bits porque el máximo número en decimal que podemos obtener es que el que se da cuando a y b tienen sus valores máximos (9) y el acarreo de entrada carry_in es igual a ‘1’; el resultado de la suma (a + b + carry_in) es 19, y en binario sería ‘10011’ (los cinco bits mencionados). Para el caso de que la suma de a y b sea mayor que 9, aplicaremos un factor de corrección que sería restar 10 al valor obtenido y aumentar 1 el dígito de las decenas. Y restar diez equivale en binario a sumar 6 (‘0110’). Un ejemplo: si a es 5 y b es 7, la suma es 12 y debemos realizar la corrección. Empezamos sumando 5 y 7. Sus correspondientes en binario son ‘0101’ para el 5 y ‘0111’ para el número 7. El resultado es 12, que en binario se representa como ‘1100’.

1 1 1 decimal 0 1 0 1 → 5

+ 0 1 1 1 → 7 1 1 0 0 → 12

Vemos que este valor es superior a 9, y por tanto no es un valor BCD válido. Entonces hemos de aplicar una corrección para obtener el valor correspondiente en BCD, donde el número 12 se representaría con dos dígitos de cuatro bits cada uno; un primer grupo para el 1 ‘0001’, y otro grupo para el 2 ‘0010’. Para pasar de binario a BCD vamos a sumar 6 (en binario ‘0110’):

1 1 1 1 0 0 → 12

+ 0 1 1 0 → 6 1 0 0 1 0

Obtenemos ‘10010’, donde debemos leer los últimos cuatro bits para el primer dígito decimal ‘0010’ y que equivalen al número 2, y el bit de más peso, ‘1’, que formaría parte del siguiente dígito decimal, que sería un 1. Por tanto, tendríamos como resultado dos dígitos decimales, un dígito decimal de las decenas igual a 1, y otro para las unidades que sería un 2. Hemos pasado del valor 12, ‘10010’ en binario, a su equivalente en nomenclatura BCD, ‘0001 0010’.

Equivale a un dígito BCD de valor 2 (‘0010’)

Equivale a un dígito BCD de valor 1 (‘0001’)

Page 23: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 23 -

Decimal 12 Binario 1100 BCD 0001 0010

En resumen:

• Si a + b + cy_in ≤ 9, a + b + cy_in = c, acarreo de salida = 0 (3.1) • Si a + b + cy_in > 9, a + b + cy_in = (c + 6) mod 16, acarreo de salida = 1 (3.2)

A continuación podemos ver una simulación del funcionamiento de este bloque:

Figura 3.5. Simulación del sumador de 1 dígito decimal Podemos observar como se realiza la corrección cuando a + b > 9, obteniendo como resultado en c el dígito de las unidades, y el dígito 1 (‘0001’) de las decenas en el acarreo de salida (cy_out).

Page 24: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 24 -

3.2.1.1.2 Sumador de n dígitos decimales Para obtener el sumador de n dígitos BCD vamos a interconectar n sumadores de 1 dígito decimal (el bloque que hemos creado antes). Gracias a la entrada carry_in de cada bloque, podemos propagar el acarreo de manera que el resultado obtenido sea el correcto.

Figura 3.6. Diagrama de bloques del sumador de n dígitos decimales

La interconexión de los bloques sencillos creará el sumador de n dígitos BCD,

Figura 3.7. Sumador de n dígitos decimales donde tendremos dos entradas, x e y, de n dígitos BCD (4n bits), y una salida z que será el resultado de la operación. Además, en el caso de que haya desbordamiento en z, la salida out_carry se pondrá a ‘1’. La entrada ini_carry en este bloque se corresponde con el acarreo de entrada del primer sumador de 1 dígito BCD.

Page 25: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 25 -

A continuación se muestra la simulación de unos ejemplos para n = 4:

Figura 3.8. Simulación del sumador de 4 dígitos decimales Podemos ver como en la tercera operación (x = 3050, y = 8070), el acarreo de salida está a nivel alto, lo que indica que el resultado es z = 11120.

Page 26: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 26 -

3.2.1.2 Restador El objetivo es crear un bloque que dados dos valores de entrada de n dígitos, x e y, calcule la diferencia z, e indique mediante una señal de salida denominada carry_out si el resultado ha sido positivo (carry_out = ‘0’) o negativo (carry_out = ‘1’),

Figura 3.9. Restador de n dígitos decimales Para ello, nos basaremos en dos operaciones básicas; una es la suma descrita en el apartado anterior, por lo que utilizaremos el Sumador de n dígitos decimales, y la otra es la utilización del complemento a 10n del valor y de entrada. El complemento a 10n de un número se puede obtener a partir de calcular el complemento a 9 de cada dígito (con un bloque que haga esta función) y sumando 1 al resultado. Un valor decimal x puede expresarse como: xn-1 xn-2 … x1 x0 = xn-1 · 10n-1 + xn-1 · 10n-2 + … + x1 · 10 + x0, (3.3) y su complemento a 9 equivale a 9 – xn-1 9 – xn-2 … 9 – x1 9 – x0 = 10n – 1 – (xn-1 xn-2 … x1 x0), (3.4) por lo que podemos establecer la siguiente igualdad: 10n – (xn-1 xn-2 … x1 x0) = (9 – xn-1 9 – xn-2 … 9 – x1 9 – x0) + 1 (3.5) Es decir, el complemento a 10n de un valor x equivale a realizar el complemento a 9 de cada dígito y sumar 1 (lo que ya habíamos avanzado anteriormente). Se puede calcular la resta mediante la expresión x + (10n – y), que plantea dos casos posibles:

• Si x ≥ y: x + (10n – y) ≥ 10n , siendo z = x – y, con carry_out = ‘1’ (3.6) • Si x < y: x + (10n – y) < 10n , siendo z = 10n + (x – y), con carry_out = ‘0’ (3.7)

Page 27: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 27 -

3.2.1.2.1 Cálculo del complemento a 9 (bloque “nine_complement.vhd”) Diseñamos un bloque que dado un dígito BCD de entrada (e), calcule su complemento a 9 (s). Este bloque estará controlado por una señal de entrada denominada add_sub, encargada de habilitar o no la operación. Si su valor es ‘1’, s mostrará el complemento a 9 de e; en caso contrario s tomará el mismo valor que e.

Figura 3.10. Bloque de complemento a 9 de un dígito BCD Dado un dígito BCD e de cuatro bits (e3 e2 e1 e0), su complemento a 9 (s3 s2 s1 s0) se obtiene mediante la operación ‘1001’ – e3 e2 e1 e0 (o su equivalente, ‘1001’ + e3’ e2’ e1’ e0’ + 1, es decir, sumando al minuendo el complemento a 2 del sustraendo). Las expresiones resultantes son las siguientes:

3213

212

11

00

eees

eeseses

⋅⋅=

⊕===

(3.8)

Si añadimos la señal de control add_sub, dichas expresiones quedan modificadas de esta forma:

( )32133

2122

11

000

__

)(__

__

eeesubaddesubadds

eesubaddesubadds

esesubaddesubadds

⋅⋅⋅+⋅=

⊕⋅+⋅=

=⋅+⋅=

(3.9)

Figura 3.11. Ejemplo del funcionamiento del bloque de complemento a 9

Page 28: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 28 -

3.2.1.2.2 Sumador/Restador en complemento a 10n Para implementar el restador utilizaremos, como hemos explicado antes, el sumador de n dígitos y el bloque de complemento a 9 (nine_complement.vhd). El diagrama de bloques resultante sería el mostrado a continuación:

Figura 3.12. Restador de n dígitos decimales Si nos fijamos en la Figura 3.12, podemos ver que la señal de control add_sub nos permite realizar las operaciones de suma y resta:

• Si add_sub = ‘0’, la señal y no se modifica y tenemos la operación suma (z = x + y)

• Si add_sub = ‘1’, lo que entra al sumador es el complemento a 9 de y; además la señal de entrada del sumador ini_carry (acarreo de entrada) toma el valor de add_sub, por lo que la operación que se realiza es la resta (z = x + y’ + ini_carry).

Debido a que podemos realizar las dos operaciones con un mismo bloque, lo denominaremos Sumador/Restador de n dígitos.

Page 29: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 29 -

3.2.1.3 Sumador/Restador, representación con signo y magnitud (bloque “n_adder_subs.vhd”) Observemos otra vez en el último bloque creado (Figura 3.12). Hemos visto que esta estructura nos permite realizar las operaciones de suma y resta. Pongamos un par de ejemplos sobre la resta siendo n = 3:

• Si x = 735 e y = 177 (su complemento a 9 es 822), tendremos 735 + 822 + 1 (del acarreo de entrada, valor de la señal add_sub). El resultado será positivo e igual a 578, con el acarreo de salida (out_carry) igual a 1.

• Si x = 485 e y 823 (su complemento a 9 es 176), tendremos 485 + 176 + 1. El

resultado será 662 con un acarreo de salida igual a 0 (resultado negativo). En este último caso, para saber el resultado exacto de la operación debemos calcular el complemento a 10n del valor z que hemos obtenido; es decir, calcular el complemento a 9 de cada dígito de z y sumar 1 al resultado obtenido. Esto lo hacemos mediante una modificación de la arquitectura anterior, por lo que el diagrama de bloques final del Sumador/Restador de n dígitos BCD será el siguiente:

Sumador de n

dígitos decimalesini_carrycarry_out

y(4n-1:0)

4n

x(4n-1:0)

4n

4nz1

Complemento a 9

4n

add_sub

Complemento a 9

4n

‘1’

4n

ini_carry ‘0’

z3

z1

4n

0 1

4n

z(4n-1:0)

add_sub

oc Sumador de n

dígitos decimalesini_carry

4n

Figura 3.13. Sumador/Restador de n dígitos decimales

Page 30: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 30 -

Esta modificación implica un cambio en el significado del valor del acarreo de salida del bloque (denominado carry_out), cuando realizamos la operación resta:

• Si carry_out = ‘0’, el resultado de la resta es no negativo (x > y)

• Si carry_out = ‘1’, el resultado de la resta es negativo (x < y) Hemos añadido otro bloque que complementa a 9 el resultado z1 de la primera etapa y posteriormente suma 1, lo que genera la señal z3. Dependiendo de los valores de add_sub y oc (acarreo de la primera etapa), el multiplexor seleccionará z1 o z3. Concretamente, cuando el resultado de la resta sea positivo (carry_out = ‘0’), el multiplexor seleccionará el canal 0 (z1), y si el resultado es negativo (carry_out = ‘1’) seleccionará el canal 1 (z3). A modo de resumen, el Sumador/Restador de n dígitos decimales presenta las siguientes características:

add_sub Operación carry_out Resultado 0 Suma 0 Exacto 0 Suma 1 Hay desbordamiento 1 Resta 0 Positivo 1 Resta 1 Negativo

Tabla 3.1. Operaciones del Sumador/Restador

A continuación mostramos unos ejemplos de la simulación para n = 4: En modo resta (add_sub = ‘1’):

Figura 3.14. Simulación del Sumador/Restador en modo resta

Page 31: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 31 -

En modo suma (add_sub = ‘0’):

Figura 3.15. Simulación del Sumador/Restador en modo suma

Page 32: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 32 -

3.2.2 Multiplicador En este apartado crearemos un módulo que multiplique dos valores de entrada, x e y, de n y m dígitos BCD respectivamente, y muestre el resultado en z, de n + m dígitos BCD.

Figura 3.16. Multiplicador de NxM dígitos BCD Para ello lo primero que haremos será definir una estructura básica que realizará la multiplicación de dos dígitos BCD (multiplicador de 1x1 dígitos BCD), después realizaremos un bloque que multiplique un número de n por 1 dígitos BCD, y finalmente el multiplicador de NxM dígitos BCD. 3.2.2.1 Multiplicador de 1x1 dígitos BCD (bloque “one_digit_multiplier.vhd”) El producto decimal se puede obtener a través del producto binario y una etapa de corrección posterior. La etapa básica sería un multiplicador de 1x1 dígitos BCD, es decir, dos entradas de 1 dígito BCD cada una. Ésta se puede implementar a partir de un circuito combinacional.

Multiplicador de 1 dígito BCD

a(3:0) b(3:0)

44

u(3:0)

4

d(3:0)

4

Figura 3.17. Multiplicador de 1x1 dígitos BCD

Page 33: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 33 -

80 40 20 10 8 4 2 1 p3 p2 p1 p0 p4 p4 p4

+ p5 p5 p5 p6 p6 p6 d3 d2 d1 d0 u3 u2 u1 u0

Tenemos A y B que son dos dígitos BCD (a3 a2 a1 a0 y b3 b2 b1 b0 respectivamente). El producto BCD de ambos dígitos se puede expresar como: UDBA +⋅=⋅ 10 , (3.10) es decir, la cifra de las decenas multiplicada por 10 más las unidades. El producto binario de A y B se puede expresar en un primer paso como un número de 7 bits tal que: 0123456 pppppppPBA ==⋅ (3.11) Son un máximo de 7 bits porque el resultado máximo que podemos tener en esta operación es 81 en decimal, que corresponderá al caso de que A y B tengan su valor máximo, y este es 9. La representación binaria del número 81 es ‘1010001’ (7 bits). Podemos convertir el número binario P a código BCD mediante sumas binarias tras corregir los términos descritos en la Figura 3.18. La primera fila indica el peso de cada dígito BCD. Los pesos de p3 p2 p1 p0 son los mismos que para el valor binario. Pero los pesos de p4 p5 y p6 se pueden descomponer en los valores BCD de la Figura 3.18. Concretamente, p4 (cuyo peso es 16 en binario) se puede descomponer como (10, 4, 2), p5 (peso binario igual a 32) se puede descomponer en (20, 10, 2) y por último p6 (peso binario 64) como (40, 20, 4).

Figura 3.18. Reducción aritmética de binario a BCD Sumamos los términos y obtenemos las expresiones que nos darán el valor de las unidades (uu) y las decenas (dd):

56456

56440123

00000

pppppddppppppppuu

+=++=

(3.12)

Dada esta última expresión de uu, podemos ver que su valor estará entre 0 y 27 (según los valores de p0, p1, p2, p3, p4, p5 y p6). Si el valor de uu es superior a 9 (con lo que se necesitaría de más de 1 dígito BCD para representarse) deberemos realizar una corrección para obtener un resultado correcto. A continuación definimos dichos términos de corrección:

• Si uu ≤ 9: no hacemos ninguna corrección, el valor es correcto, • Si 9 < uu ≤ 19: sumamos 1 a dd, (añadimos 1 a las decenas y 6 a las unidades; esto

último equivale a restar 10), • Si 19 < uu: sumamos 2 a dd, (añadimos 2 a las decenas y 12 a las unidades; esto

último equivale a restar 20).

Page 34: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 34 -

Definiremos una variable para cada caso y mediante las siguientes expresiones booleanas sabremos cual tenemos en cada momento.

• Si uu es mayor o igual a 10:

)(9 1234 uuuuuuuugt ∨⋅∨= (3.13)

• Si uu es mayor o igual a 20:

)(20 234 uuuuuugt ∨⋅= (3.14)

• Si uu se encuentra entre 10 y 19 (ambos incluidos):

2091910 gtgtstgt ⋅= (3.15) Por último obtenemos los valores finales para las decenas (d) y las unidades (u) al añadir las correcciones pertinentes: u = (uu3 uu2 uu1 uu0) + (gt20 gt9 gt10st19 0) d = (dd3 dd2 dd1 dd0) + (0 0 gt20 gt10st19) (3.16) Simulación

Figura 3.19. Muestra de la simulación del multiplicador de 1x1 dígitos BCD 3.2.2.2 Multiplicador de Nx1 dígitos BCD (bloque “n_by_one_multiplier.vhd”) Un multiplicador de Nx1 dígitos BCD se puede construir a partir de n multiplicadores de 1x1 dígitos BCD seguido de sumadores BCD. Por tanto, para realizar este bloque utilizaremos dos que hemos creado anteriormente; uno será el multiplicador que acabamos de hacer (multiplicador de 1x1 dígitos BCD, one_digit_multiplier.vhd) y el otro será el sumador de 1 dígito BCD (one_digit_adder.vhd).

Page 35: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 35 -

Pongamos un ejemplo: si n es igual a 3, tendremos la siguiente estructura,

Multipl. 1x1 BCD

4 4

u0

4

yx0

d0

4Multipl. 1x1 BCD

4 4

u1

4

yx1

d1

4

4 4

u2

4

yx2

d2

4 Multipl. 1x1 BCD

Figura 3.20. Multiplicador de 3x1 dígitos BCD (parte 1) donde x será el número de 3 dígitos BCD (x2 x1 x0). Cada multiplicador genera un valor para las unidades (ux) y uno para las decenas (dx); este último será el que deba sumarse a las unidades del siguiente multiplicador. Esta estructura nos muestra que necesitaremos un sumador de n + 1 dígitos BCD. El resultado z (formada por 4 dígitos BCD) será el siguiente: z = (0 u2 u1 u0) + (d2 d1 d0 0) (3.17)

Sumador 1 dígito BCD

z0

4

4

u0

4

‘0’

Sumador 1 dígito BCD

z1

4

4

u1

4

d0

Sumador 1 dígito BCD

z2

4

4

u2

4

d1

Sumador 1 dígito BCD

z3

4

4

‘0’

4

d2

Figura 3.21. Multiplicador de 3x1 dígitos BCD (parte 2) Viendo este ejemplo podemos afirmar que, para un multiplicador de Nx1 dígitos BCD, necesitaremos n multiplicadores 1x1 y n + 1 sumadores de 1 dígito.

Page 36: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 36 -

Tendremos dos señales de entrada: un valor x de n dígitos (xn-1 xn-2 … x2 x1 x0) y un valor y de 1 dígito, lo que generará una señal de salida z (zn zn-1 zn-2 … z2 z1 z0).

Figura 3.22. Multiplicador de Nx1 dígitos. Incluye n multiplicadores 1x1 y n + 1 sumadores de 1 dígito A continuación se muestra un ejemplo de la simulación del bloque para n = 5:

Figura 3.23. Simulación del multiplicador Nx1 dígitos BCD

Page 37: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 37 -

3.2.2.3 Multiplicador de NxM dígitos BCD (bloque “n_by_m_multiplier.vhd”) En este bloque tenemos como datos iniciales dos números decimales, x e y, de n y m dígitos respectivamente (xn-1 xn-2 … x2 x1 x0 e ym-1 ym-2 … y2 y1 y0). El resultado será z, un número decimal de n + m dígitos (z(n+m)-1 z(n+m)-2 … z2 z1 z0).

Figura 3.24. Multiplicador de NxM dígitos BCD También tendremos las entradas start (indica inicio de operación), clk (señal de reloj) y reset (que inicializa el bloque), y la salida done (que informa de operación realizada). Los valores n y m serán los parámetros genéricos del circuito. Para realizar esta operación vamos a crear un sistema secuencial (a diferencia de los que habíamos hecho hasta ahora, que eran combinacionales) en el que mediante un bucle, utilizaremos m veces el multiplicador de Nx1 dígitos (n_by_one_multiplier.vhd) y sumaremos y almacenaremos los resultados parciales (mediante el bloque n_adder_subs.vhd en modo suma y registros internos). Que sea un sistema secuencial ayudará a reducir el coste del mismo, ya que utilizaremos un solo multiplicador en lugar de utilizar m multiplicadores de Nx1. El algoritmo que utilizaremos será el siguiente: z := 0; for i in 1 .. m loop

z := z · 10 + x · ym-i; end loop;

Page 38: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 38 -

El diagrama de bloques del circuito es:

left shift register y

Multiplicador Nx1 dígitos BCD

44m

‘1111’y(4m-1:0)

4n

x(4n-1:0)loadshiftclk

Sumador ndígitos BCD

register zloadshiftclk

4(n+1)

x 10

z(4(n+m)-1:0)

4(n+m)

4

z_by_10

next_z

x_by_yi

int_y(m)

Figura 3.25. Diagrama de bloques del multiplicador NxM El funcionamiento es el siguiente: se inicializa el registro de desplazamiento (load = ‘1’) con el valor de y seguido de un dígito no decimal (15 = ‘1111’), que será el indicador de que ya hemos multiplicado todos los valores de y. A cada etapa (shift = ‘1’) se desplaza el valor una posición (4 bits) a la izquierda. De esta manera entrarán sucesivamente en el multiplicador Nx1 los dígitos ym-1, ym-2, … y1, y0; una señal interna detectará el ‘1111’ e indicará el fin de cálculo. En el multiplicador Nx1 tendremos en una entrada el valor de x, multiplicando cada vez por el dígito de y correspondiente. Es decir, en un primer paso el multiplicador realizaría el producto de xn-1 xn-2 … x1 x0 e ym-1. El valor resultante pasaría al sumador, donde no se modificaría ya que el registro z se inicializa con 0, y se almacenaría en dicho registro. En la siguiente etapa, se desplazará el registro de desplazamiento otra posición; en el multiplicador ahora tendremos como entradas xn-1 xn-2 … x1 x0 e ym-2. En el sumador tendremos como entradas el último producto generado y el primer valor que se almacenó en el registro z multiplicado por 10. Este proceso se repite hasta que se detecta el dígito no decimal ‘1111’ en el registro de desplazamiento que indica que se han leído todos los valores de y.

Page 39: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 39 -

En la siguiente figura podemos ver una simulación del proceso, donde hemos establecido n = 3 y m = 4:

Figura 3.26. Simulación del multiplicador NxM dígitos BCD Para controlar este sistema secuencial necesitaremos una unidad de control. Dicha unidad recibirá como señales de entrada start, clk, reset y end_of_computation, y generará las señales shift, load y done:

Figura 3.27. Unidad de control La unidad de control se puede representar con una máquina de 4 estados:

E0 E1 E2 E3

shift = 0load = 0done = 1

start = 1

end_of_ computation = 1

start = 0

start = 1 start = 0

shift = 0load = 0done = 1

shift = 0load = 1done = 0

shift = 1load = 0done = 0

end_of_ computation = 0

Figura 3.28. Máquina de estados de la unidad de control

Page 40: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 40 -

E0 es el estado inicial (señal current_state), con un bucle de espera para que la señal start pase a nivel bajo y avanzar al estado 1 (caso de que start se haya mantenido a ‘1’ como consecuencia de una operación anterior). Aquí se espera a que start sea igual ‘1’ (lo que hemos hecho ha sido detectar la transición de ‘0’ a ‘1’ de esta señal). En E2 se cargan los valores iniciales en los registros (load = ‘1’). Entonces pasamos a E3, donde se ejecutan las etapas de cálculo (shift = ‘1’) hasta que la señal end_of_computation sea igual a ‘1’, lo que significará que el dígito leído int_y es 15 (‘1111’) y ha finalizado la operación, volviendo al estado inicial y poniendo la señal done a ‘1’, indicando que el proceso ha terminado.

Page 41: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 41 -

3.2.3 Divisor 3.2.3.1 Algoritmo de división binaria Dados dos números naturales x e y, siendo x < y, el algoritmo de división binaria genera dos naturales q y r tales que: ,2 ryqx p +⋅=⋅ con r < y (3.18) Así ,22 pp ryqx −− ⋅+⋅⋅= (3.19) y

,22 pp

yrq

yx −− ⋅+⋅= siendo pp

yr −− <⋅ 22 (3.20)

El algoritmo se basa en el siguiente conjunto de igualdades: r0 = x, de modo que r0 < y, 2 · r0 = qp-1 · y + r1, con r1 < y, 2 · r1 = qp-2 · y + r2, con r2 < y, 2 · r2 = qp-3 · y + r3, con r3 < y, … 2 · rp-1 = q0 · y + rp, con rp < y, (3.21) Multiplicando la primera ecuación por 2p, la segunda por 2p-1, la tercera por 2p-2,…, y la última por 20, y sumando las p ecuaciones tenemos que: x · 2p = (qp-1 · 2p-1 + qp-2 · 2p-2 + qp-3 · 2p-3 + … + q0 · 20) y + rp (3.22) Si comparamos la expresión con (3.18), podemos obtener q y r ya que: q = 0. qp-1 qp-2 qp-3 … q0 y r = rp (3.23) En cada paso se calculan qp-i y ri en función de ri-1 e y: 2 · ri-1 = qp-i · y + ri, siendo ri < y (3.24) Se plantean dos opciones:

• 2 · ri-1 ≥ y : entonces

qp-i = 1 y ri = 2 · ri-1 – y (3.25) • 2 · ri-1 < y : entonces

qp-i = 0 y ri = 2 · ri-1 (3.26)

Page 42: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 42 -

3.2.3.2 Algoritmo de división BCD El algoritmo de división binaria se puede utilizar cualquiera que sea el sistema de numeración. Si trabajamos en base 10, la única condición para poder utilizarlo es que todas las operaciones se hagan en base 10. El algoritmo que utilizaremos será el siguiente: r := x; q := 0; ulp := 0.5; for i in 1 .. p loop

two_r := 2*r; dif := two_r - y; if dif < 0 then r := two_r; else r := dif; q := q + ulp; end if; ulp := ulp/2;

end loop; Las operaciones en BCD que utilizaremos serán la multiplicación por 2, la resta con generación de signo y la suma. Además, la representación BCD de 1/2, 1/22, ..., 1/2p será calculada sobre la marcha. 3.2.3.3 Error generado Si se ejecutan p etapas, el error es menor que 1/2p (según el algoritmo). Supongamos que el objetivo sea que el resultado se escriba con m dígitos fraccionarios y que el error sea menor que 1/10m (significa que el resultado obtenido es el cociente exacto truncado). Para ello basta con que se cumpla la siguiente relación:

mp

⎟⎠⎞

⎜⎝⎛<⎟

⎠⎞

⎜⎝⎛

101

21 , es decir )10(log2⋅> mp , o sea que mp ⋅> 3.3 (3.27)

Page 43: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 43 -

3.2.3.4 Divisor BCD (bloque “divider.vhd”) El divisor BCD será un módulo que realice la división entre dos valores de entrada, x / y, donde x < y (para que el algoritmo funcione), dando como resultado el cociente q de m dígitos decimales (qm-1 qm-2 … q2 q1 q0). También tendrá como entradas las señales start (inicio de operación), clk (señal de reloj) y reset (que inicializa el bloque), y la salida done (que informa de operación realizada).

Figura 3.29. Divisor BCD El cociente q es una salida de m dígitos. Internamente, el cociente debe generarse con p dígitos, donde p es del orden de 3.3m (según hemos explicado anteriormente). Llámese qq al cociente interno con p dígitos. El cociente q (el resultado que nosotros veremos) consta de los m dígitos más significativos de qq. Los valores de n (dígitos de los valores de entrada), m (dígitos y por tanto precisión del resultado, el cociente), p (número de iteraciones que se realizarán) y logp (número de bits necesario para representar p) serán los parámetros genéricos del modelo.

Page 44: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 44 -

Basándonos en el algoritmo de ejecución creamos el siguiente diagrama de bloques:

Sumador/Restador n dígitos BCD

Multiplicador Nx1 dígitos BCD

r

44n

‘0010’

4n+4

Sumador/Restador n dígitos BCD

y(4n-1:0)

4n

carry_out add_sub ‘1’

0 1

rr_y(4n-5:0)

rr

load

0 1

ulp

4p

qq

4p

carry_out add_sub ‘0’

4n 4p

ini.: x(4n-1:0)clk initially: 0

4n4p

rq(4m-1:0)

qq4p

4p-4(p-m)

44p

‘0101’ulp

load initially: 0.5clk

4p

ulp

4p4p+4

Multiplicador Nx1 dígitos BCD

Figura 3.30. Diagrama de bloques del divisor BCD Inicialmente cargamos en el registro r el valor de entrada x. Para calcular el doble de r utilizamos un multiplicador de Nx1 dígitos BCD (n_by_one_multiplier.vhd). En una entrada tendremos el valor r y en la otra el dígito 2 (‘0010’ en binario). La diferencia entre el doble de r (2r, señal rr) y el valor decimal de entrada y, la calculamos mediante un Sumador/Restador de n dígitos BCD (n_adder_subs.vhd) en modo resta (señal de entrada add_sub = ‘1’). Si el resultado de la resta es positivo (rr > y) entonces carry_out = ‘0’ y se almacenarán en el registro r los n dígitos menos significativos de la diferencia recién calculada (rr - y). Si por el contrario rr < y, carry_out = ‘1’, se almacenarán en el registro los n dígitos menos significativos del valor de rr.

Page 45: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 45 -

El registro qq donde se almacenan los valores intermedios del cociente se inicializa a 0. La suma de qq y ulp la calculamos mediante un Sumador/Restador de n dígitos BCD (n_adder_subs.vhd) que opere en modo suma (add_sub = ‘0’). Si el resultado antes calculado de rr - y es positivo, se almacenará en el registro qq el resultado de qq + ulp; si es negativo, lo que se almacene será el valor de qq. La señal ulp (Unit in the Least significant Position, unidad en la posición menos significativa) es un número que al final del cálculo tendrá p dígitos. Su registro (register_ulp) se inicializa con el valor 0.5 (‘0000 0101’ en código BCD). En cada iteración irá tomando los valores 0.5, 0.25, 0.125, 0.0625, y así sucesivamente; es decir, multiplicando el anterior valor por 5 (mediante el multiplicador de Nx1 dígitos, n_by_one_multiplier.vhd) y desplazando el resultado 4 bits a la derecha (o lo que es lo mismo, introduciendo un 0 decimal delante). Al ser la salida del multiplicador por 5 un número de p + 1 dígitos, sólo utilizaremos los p dígitos de más peso (lo que equivale a dividir por 10). Al acabar el cálculo de la operación (señal zero = ‘1’), obtendremos el cociente q de truncar el último valor almacenado en el registro qq, a partir del número de dígitos m que hayamos seleccionado. Unidad de control Este sistema que hemos creado también es secuencial y necesitará de una unidad de control que lo gobierne.

Figura 3.31. Unidad de control del divisor La unidad de control genera las señales load (escritura de los valores iniciales en los registros), ce (actualización de los registros) y done (operación finalizada). La señal zero vendrá controlada por un contador de p estados (este número se representa con logp bits, como hemos dicho antes). Dicha señal se pondrá a ‘1’ cuando se ejecute el paso p de la iteración.

Page 46: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 46 -

La máquina de estados asociada a la unidad de control es la siguiente:

Figura 3.32. Máquina de estados de la unidad de control del divisor Simulación A continuación mostramos un ejemplo de la simulación del sistema para los valores genéricos n = 3, m = 8, p = 27 y logp = 5:

Figura 3.33. Simulación del divisor La división entre x = 335 e y = 927 genera el cociente q = 36138079, que representa 0.36138079 (como x < y, el primer dígito siempre es 0). Al haber definido m = 8, el cociente está representado por 8 dígitos decimales.

Page 47: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 47 -

Podemos observar con mayor facilidad en la Figura 3.34 la transición entre estados, y vemos como, desde el estado 0 (señal current_state) y dado que la señal start es ‘0’, pasamos al estado 1 (en caso de que start se hubiera mantenido a ‘1’ como resultado de un cálculo anterior, el sistema esperaría a que dicha señal se pusiera a ‘0’).

Figura 3.34. Ampliación de la Figura 3.33 En el estado 1 y tras detectar un flanco de subida de la señal start, pasamos al estado 2, donde la unidad de control activa (a ‘1’) la señal load y se escriben los valores iniciales en los registros. La señal done se pone a ‘0’ indicando que hay una operación en curso. Tras un ciclo de reloj pasamos al estado 3 y se inicia el cálculo; aquí empieza a funcionar el contador regresivo (count) de p estados (27 en el ejemplo, de 26 a 0) que determina el número de iteraciones a realizar. También se activa la señal ce que permitirá actualizar los registros. Cuando el contador llegue a 0, dejarán de actualizarse los registros (ce = ‘0’) y se activará la señal zero informando del fin de cálculo (esto se puede ver en la Figura 3.33), volviendo al estado 0 y poniéndose el indicador de operación realizada done a nivel alto.

Page 48: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 48 -

3.3 Diseño de la Unidad Aritmética Decimal (bloque “arithmetic_unit.vhd”) El siguiente paso es la definición de la Unidad Aritmética Decimal, una estructura que integre los tres bloques anteriores (Sumador/Restador de n dígitos decimales, Multiplicador de NxM dígitos BCD y Divisor BCD).

Figura 3.35. Unidad Aritmética Decimal Los parámetros genéricos del modelo serán:

• n: tamaño de los operandos (en dígitos decimales) de x e y • p: número de etapas de la división • logp: número de bits necesario para representar p

Este bloque estará controlado por una señal de entrada llamada operation, mediante la cual se indicará a la unidad la operación a realizar:

operation Operación Resultado 00 Suma z = x + y 01 Resta z = x - y 10 Multiplicación z = x · y 11 División z = x / y (con una precisión de 2n dígitos fraccionarios)

Tabla 3.2. Operaciones de la Unidad Aritmética Decimal

Tanto para la suma como la resta z tendrá un tamaño de 4n + 1 bits (el bit de mayor peso corresponde a la señal carry_out del bloque Sumador/Restador), mientras que para la multiplicación y división el tamaño será de 8n bits. En la multiplicación y la división el cálculo empieza con un flanco de subida de la señal de entrada start. La bandera done se pone a ‘0’. Una vez disponible el resultado, done tomará el valor ‘1’.

Page 49: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 49 -

El diagrama de bloques de la unidad se muestra a continuación:

8n8n4n

z(8n-1:4n) done

done1 done2

‘1’

s1 s2 s3

c_out Sumador/Restadorn dígitos BCD

Multiplicador de NxM dígitos BCD

Divisor de ndígitos BCD

4n

clkreset

clkreset

4n 4n 4n 4n 4n

operation0

operation1

start

carry_out add_sub

x(4n-1:0)y(4n-1:0)

start1 start2

00 01 10 11

z(4n-1:0)

operation

4n

MUX-100 01 10 11

4n

MUX-200 01 10 11

4n

MUX-3

Figura 3.36. Diagrama de bloques de la Unidad Aritmética Decimal De cara a la implementación en la FPGA, el operando y del Multiplicador de NxM dígitos decimales pasará de estar formado por m dígitos a estarlo por n (podemos decir que ahora el bloque es un “Multiplicador de n dígitos decimales”) De esta manera unificamos los valores de entrada, que siempre estarán formados por n dígitos decimales. Utilizaremos el bit de menor peso de la señal operation para indicar al Sumador/Restador la operación a realizar (entrada add_sub de éste). Para habilitar el bloque multiplicador utilizaremos la señal start1, que es la salida de una puerta AND de tres entradas (los dos bits de operation, con el de menor peso negado, y start). Para el divisor utilizaremos start2, resultado de una puerta AND también de tres entradas, pero esta vez sin negar el bit de menos peso de operation.

Figura 3.37. Circuito generador de las señales start1 y start2

Page 50: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 50 -

La salida del primer multiplexor (MUX-1) muestra el resultado de las operaciones suma (operation = ‘00’) o resta (operation = ‘01’), y la parte baja del resultado de las operaciones multiplicación (operation = ‘10’) o división (operation = ‘11’), que sería z(4n-1:0). El segundo multiplexor recibe a través de sus dos primeros canales el valor de la señal carry_out del Sumador/Restador (llamada c_out). Como este valor ocupa 1 solo bit, los otros bits del dígito de menos peso serán 0 (el dígito de menor peso, 4n+3:4n, estará formado por ‘0 0 0 c_out’); los demás dígitos (8n-1:4n+4) serán 0. Para la multiplicación y la división mostrará la parte alta del resultado, los dígitos de mayor peso (8n-1:4n). MUX-3 muestra el valor actual de la señal done, que estará a nivel alto excepto cuando se realice el cálculo de la multiplicación o de la división (periodo en que la señal se pondrá a nivel bajo, debido a que done1 o done2 tomarán este valor). A continuación se muestra una simulación del sistema con los parámetros n = 8 y p = 56 (en consecuencia logp = 6), para las diferentes operaciones:

Figura 3.38. Simulación de la Unidad Aritmética Decimal (suma y resta) En este ejemplo podemos ver las operaciones suma y resta. Los valores de entrada son x = 00867335 e y = 02350927 (ambos de 8 dígitos BCD, ya que habíamos establecido n = 8). Primero se realiza la suma (operation = ‘00’), siendo el resultado z = 03218262; como no hay desbordamiento en el resultado, c_out (acarreo de salida) es 0. Al cambiar operation a ‘01’ obtenemos la resta, siendo z = 01483592; en este caso el dígito de menor peso de la parte alta de z es 1 (00000001), lo que indica que el resultado es negativo (z = – 1483592). Seguidamente mostramos la simulación de la unidad cuando queremos realizar la multiplicación de dos valores (seleccionando operation = ‘10’):

Page 51: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria descriptiva

- 51 -

Figura 3.39. Simulación de la Unidad Aritmética Decimal (multiplicación) Al iniciarse el cálculo, la señal que lo indica (done1) se pone a ‘0’, lo que provoca que la salida del sistema done también lo haga. Al acabar la ejecución, done1 vuelve a nivel alto y done también. Vemos como start1 se activa habilitando el multiplicador, en cambio start2 sigue a nivel bajo. Por último tenemos la simulación de la unidad cuando ejecutamos la operación de división (operation = ‘11’).

Figura 3.40. Simulación de la Unidad Aritmética Decimal (división) Observamos la influencia de la señal done2 en done (tomando el valor ‘0’ durante la ejecución, las p etapas que habíamos explicado anteriormente). El resultado z se debe leer como 0.3689331910348556.

Page 52: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal

4. MEMORIA EXPERIMENTAL

Page 53: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 53 -

4.1 Descripción del proceso ........................................................................................................... 54

4.2 Especificaciones ........................................................................................................................ 54

4.3 Elementos necesarios................................................................................................................ 55

4.4 Arquitectura a desarrollar ...................................................................................................... 55

4.5 Módulos IP de terceros utilizados........................................................................................... 57

4.5.1 Microcontrolador PicoBlaze (módulo “kcpsm.vhd”)........................................................ 57

4.5.2 Interfaz LCD (módulo “lcd_interface.vhd”)..................................................................... 58

4.6 Memoria de programa (módulo “program_memory.vhd”) ................................................... 60

4.7 Generación del circuito (módulo “main.vhd”) ....................................................................... 62

4.8 Asignación de pines en la FPGA (archivo “pins.ucf”) .......................................................... 63

4.9 Implementación en la FPGA ................................................................................................... 65

4.9.1 Generación del archivo ..................................................................................................... 66

4.9.2 Implementación en la FPGA ............................................................................................ 68

Page 54: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 54 -

4.1 Descripción del proceso En este capítulo describiremos la implementación del componente virtual que hemos creado, la Unidad Aritmética Decimal, en la plataforma FPGA Spartan-3E Starter Kit, con el fin de comprobar su correcto funcionamiento. Para ello debemos estructurar un sistema completo, con una CPU que gobierne el sistema, una memoria de programa con el juego de instrucciones que se ejecutarán, una interfaz que visualice los datos en la pantalla de la placa, y nuestra unidad, como principales elementos. Como CPU utilizaremos un módulo IP proporcionado por Xilinx, el microcontrolador de 8 bits PicoBlaze (kcpsm.vhd); para la interfaz de visualización de datos, el módulo lcd_interface.vhd, que es un módulo previamente generado en proyectos anteriores El primer paso consistirá en la creación de la memoria de programa que utilizará PicoBlaze, utilizando la aplicación pBlaze IDE. Después crearemos un modelo VHDL que incluya los módulos mencionados antes. Por último, implementaremos todo el diseño en la FPGA mediante el paquete Xilinx ISE Desing Suite. 4.2 Especificaciones Consideremos las dos líneas de 16 caracteres cada una que posee la placa, y que se distribuyen de la siguiente manera: en la primera línea, los 8 primeros dígitos (BCD) corresponden al operando x, y los 8 últimos al operando y. La segunda línea será el resultado z.

Figura 4.1. Posicionamiento de los dígitos en el display Un primer pulso (pulso 0) de synch (señal de sincronización) borra el display. Mediante los interruptores SW3, SW2, SW1 y SW0 (pesos 8, 4, 2, 1 respectivamente) el dígito de entrada, y con el pulsador synch procedemos a almacenarlo en el registro interno correspondiente y visualizarlo en pantalla. Tras haber introducido los 16 dígitos (los 8 primeros para el operando x y los 8 siguientes para el operando y), un nuevo pulso de synch muestra en el display el resultado de la suma; en los sucesivos pulsos de synch veremos los resultados de la resta, la multiplicación y la división. Un último pulso (pulso 21) dará la señal para limpiar el visualizador.

Page 55: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 55 -

La siguiente figura ilustra el proceso que acabamos de describir:

pulso 2 0 2

pulso 3 0 2 8

pulso 1 0

pulso 0

pulso 16 0 2 8 6 7 3 3 5 5 0 2 9 9 7 2 3

...

pulso 17 0 2 8 6 7 3 3 5 5 0 2 9 9 7 2 30 0 0 0 0 0 0 0 5 3 1 6 7 0 5 8

pulso 18 0 2 8 6 7 3 3 5 5 0 2 9 9 7 2 30 0 0 0 0 0 0 1 4 7 4 3 2 3 8 8

...

pulso 21

Figura 4.2. Funcionamiento del sistema 4.3 Elementos necesarios De acuerdo a las especificaciones, precisamos los siguientes elementos de la Spartan-3E Starter Kit:

• Interruptores SW3, SW2, SW1, SW0 para seleccionar el dígito BCD de entrada data_in.

• Pulsadores para las señales synch (de sincronización) y reset. • Visualizador LCD de la placa. • Oscilador de 50 MHz.

4.4 Arquitectura a desarrollar Debemos elaborar una arquitectura capaz de llevar a cabo el proceso descrito anteriormente. Dicha arquitectura deberá disponer (entre otras cosas) de:

• Una CPU que controle la entrada de dígitos, la codificación (a ASCII) de los datos y la ejecución de las diferentes operaciones. Las operaciones se definirán mediante un juego de instrucciones en lenguaje ensamblador, que posteriormente formarán la memoria de programa.

• Una interfaz para el display LCD. • La Unidad Aritmética Decimal.

Page 56: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 56 -

Podemos definir la arquitectura del sistema mediante el siguiente diagrama de bloques:

15 …. 0

Unidad Aritmética Decimal

z (15:0)

startreset

clk

x (7:0)y (7:0)operation

clkRegistro 8*4 bits

PicoBlaze (CPU and

program memory) write_strobeport_idreset

clk

in_port

out_port

data_in synch

mult_out

done

Registro Registro clk

d_writei_writetemp_write

lcd_interface

lcd_data lcd_rs lcd_rwlcd_e

Registro 8*4 bits

Registro 2 bits

ready

Figura 4.3. Diagrama de bloques del sistema Como CPU del sistema utilizaremos el microcontrolador PicoBlaze proporcionado por Xilinx; emplearemos dos componentes virtuales más, el modelo VHDL de una interfaz LCD y nuestra Unidad Aritmética Decimal, que es el módulo que queremos testear.

Page 57: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 57 -

4.5 Módulos IP de terceros utilizados En este apartado hablaremos un poco sobre los dos componentes virtuales que utilizaremos y que son suministrados por terceros. 4.5.1 Microcontrolador PicoBlaze (módulo “kcpsm.vhd”) PicoBlaze es el nombre del modelo VHDL de un microcontrolador de 8 bits (KCPSM – Constant (K) Coded Programmable State Machine) desarrollado por Xilinx y que puede ser integrado en las FPGA de la familia Spartan-3E, entre otras. Este módulo no requiere soporte externo y proporciona un entorno flexible para conectarlo a otros componentes. Se suministra como descripción VHDL. El ensamblador pBlaze IDE permite crear el modelo VHDL de la memoria de programa que utilizará el microcontrolador. Algunas características de PicoBlaze son:

• Posee 16 registros de 8 bits de propósito general (s0 a sF). • 256 puertos de entrada y 256 de salida. • Rápida respuesta a interrupciones (el peor caso es de 5 ciclos de reloj). • Soporta programas de hasta 256 instrucciones. • El tamaño de las instrucciones es de 16 bits. • Todas las instrucciones se ejecutan en 2 ciclos de reloj.

Estructura A continuación podemos ver el diagrama de bloques del módulo PicoBlaze.

Figura 4.4. Diagrama de bloques del módulo PicoBlaze

Page 58: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 58 -

Arquitectura

Figura 4.5. Arquitectura interna de PicoBlaze

4.5.2 Interfaz LCD (módulo “lcd_interface.vhd”) Es un módulo VHDL que añade la funcionalidad necesaria para presentar datos en el visualizador de la FPGA.

d_writei_writetemp_write

lcd_interface

lcd_data lcd_rs lcd_rwlcd_e

ready

clkreset

Figura 4.6. Módulo lcd_interface

Page 59: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 59 -

La entrada de 8 bits temp_write puede ser un carácter (código ASCII) o un comando. La entrada de control i_write envía el comando temp_write a la pantalla, y la entrada de control d_write hace lo mismo pero con un carácter (Figura 4.7). La señal ready se activa cuando la interfaz está disponible para una nueva operación.

Figura 4.7. Operaciones Este componente implementa internamente 4 retardos diferentes mediante un contador programable, para una correcta visualización de los datos en el display:

• very long: 3.218 clock cycles; at 50 MHz: 786,432 x 20 ns ≈ 16 ms;

• long: 213 clock cycles; at 50 MHz: 8,19 x 20 ns ≈ 160 μs;

• short: 50 clock cycles; at 50 MHz: 50 x 20 ns = 1 μs;

• very short: 12 clock cycles; at 50 MHz: 12 x 20 ns = 240 ns. Los comandos que utilizaremos son los siguientes:

comando (hex.) Operación 01 Limpiar el display 80 Fijar el cursor al inicio de la primera línea C0 Fijar el cursor al inicio de la segunda línea

Tabla 4.1. Comando utilizados

Page 60: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 60 -

El diagrama de bloques de la interfaz LCD es el siguiente:

0 1 2 3 sel_delay

very_shortshort long

very_long

load loadcounter

time_out(to control unit)

statustime_out

nibblece_cdsel_nibblesel_delayloadreset

clk

i_write s_write ready

lcd_data lcd_e lcd_rs lcd_write(= 0)

ce

temp_writed_write

ce_cd

status(to control unit)

cd(7..0)

cd(3..0)cd(7..4)

1 0sel_nibble

nibble(to control unit)

control unit

Figura 4.8. Circuito de la interfaz LCD 4.6 Memoria de programa (módulo “program_memory.vhd”) El primer paso consiste en realizar la memoria de programa. Para ello, realizaremos un programa en lenguaje ensamblador (decimal_unit.asm) definiendo las direcciones de entrada y salida, los registros que se emplearán y las instrucciones que se ejecutarán (incluyendo un programa principal y diversas subrutinas). Este paso lo llevaremos a cabo mediante la aplicación pBlaze IDE, que nos permitirá ensamblar y simular nuestro código, y generará, a partir de un modelo “en blanco” (my_ROM_blank.vhd) el modelo VHDL de la memoria de programa (program_memory.vhd). Definimos las direcciones de entrada según la siguiente tabla:

señal dirección z 00 a 0f

synch 10 data_in 11 ready 12 done 13

Tabla 4.2. Direcciones de entrada

Page 61: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 61 -

Y las de salida:

señal dirección y 00 a 07 x 08 a 0f

temp_wr 10 id_write 11

start 12 operation 13

Tabla 4.3. Direcciones de salida

El algoritmo utilizado sería el siguiente: external loop (infinite) send command 01 (clear) to display; send command 80 (cursor address = 00) to display; internal loop (16 times) wait for a positive edge on synch; store data_in in data; write data into x(i) and y(i); encode data; display character data; end internal loop; wait for a positive edge on synch; store 01 (addition) in data; write data into operation; display z; wait for a positive edge on synch; store 02 (substraction) in data; write data into operation; display z; wait for a positive edge on synch; store 03 (multiplication) in data; write data into operation; start multiplier; wait for done; display z; wait for a positive edge on synch; store 04 (division) in data; write data into operation; start divider; wait for done; display z; end external loop; Con el objetivo de reducir el tamaño del código, se incluiría una subrutina (entre otras) que mostrara el resultado z en el visualizador después de cada operación: subroutine display z; send command c0 (cursor address = 40) to display; internal loop (16 times) store z(i) in data; encode data; display character data; end internal loop;

Page 62: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 62 -

4.7 Generación del circuito (módulo “main.vhd”) Con los modelos VHDL disponibles, el microcontrolador PicoBlaze (kcpsm.vhd) y la memoria de programa (program_memory.vhd), la interfaz LCD (lcd_interface.vhd) y la Unidad Aritmética Decimal (arithmetic_unit.vhd), ya podemos diseñar nuestro circuito completo. Añadiremos varios registros necesarios para el funcionamiento del sistema. El diagrama de bloques es el que hemos mostrado antes:

15 …. 0

Unidad Aritmética Decimal

z (15:0)

startreset

clk

x (7:0)y (7:0)operation

clkRegistro 8*4 bits

PicoBlaze (CPU and

program memory) write_strobeport_idreset

clk

in_port

out_port

data_in synch

mult_out

done

Registro Registro clk

d_writei_writetemp_write

lcd_interface

lcd_data lcd_rs lcd_rwlcd_e

Registro 8*4 bits

Registro 2 bits

ready

Figura 4.9. Diagrama de bloques del sistema Definiremos la Unidad Aritmética Decimal con los siguientes parámetros:

• n = 8, lo que quiere decir que los operandos x e y serán de 8 dígitos BCD cada uno, • p = 56, es el número de etapas que se ejecutarán para calcular el resultado cuando

realicemos la división, • logp = 6, que son los bits necesarios para representar el valor de p.

Page 63: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 63 -

Utilizaremos 2 registros de 32 bits (8 dígitos BCD por 4 bits cada uno) para almacenar los valores que se vayan introduciendo de los operandos x e y; en el caso de la señal operation tendremos suficiente con un registro de 2 bits. Otros 2 registros más serán necesarios para las señales temp_write y i_write/d_write de la interfaz LCD. También incluiremos un divisor de frecuencia ya que la proporcionada por el reloj de la placa es demasiado alta (50 MHz). En el circuito se añaden cuatro divisores de frecuencia que generan clk_2, clk_4, clk_8 y clk; esta última señal es la que se utilizará como señal de reloj de los diferentes bloques del circuito. Cada divisor reduce la frecuencia anterior a la mitad, por lo que tras 4 divisores, la frecuencia inicial de 50 MHz se dividirá por 16 y obtendremos una frecuencia de trabajo de 3.125 MHz. 4.8 Asignación de pines en la FPGA (archivo “pins.ucf”) El siguiente paso consiste en crear un archivo UCF (User Constraint File) que asigne las señales que utilizamos a los pines correspondientes de la Spartan-3E. Las descripciones necesarias para cada elemento de la placa se pueden encontrar en la Spartan-3E Starter Kit Board User Guide. Los interruptores SW3 (mayor peso), SW2, SW1 y SW0 (menor peso) serán asignados a los siguientes pines (entre paréntesis):

• data_in<3> → SW3 (N17) • data_in<2> → SW2 (H18) • data_in<1> → SW1 (L14) • data_in<0> → SW0 (L13)

Figura 4.10. Distribución de los interruptores SW

Page 64: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 64 -

Pulsadores:

• synch → BTN_WEST (D18) • reset → BTN_SOUTH (K17)

Figura 4.11. Pulsadores disponibles en la placa Señal de reloj:

• ext_clk → CLK_50MHz (C9)

Figura 4.12. Señales de reloj disponibles Señales de la interfaz LCD:

Señal Nombre interno PIN asociado

lcd_e LCD_E M18 lcd_rs LCD_RS L18 lcd_rw LCD_RW L17 lcd_data<3> SF_D<11> M15 lcd_data<2> SF_D<10> P17 lcd_data<1> SF_D<9> R16 lcd_data<0> SF_D<8> R15

Tabla 4.4. Asignación de pines para la interfaz LCD

Page 65: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 65 -

Figura 4.13. Interfaz LCD 4.9 Implementación en la FPGA Ahora que disponemos del modelo VHDL del circuito completo (main.vhd), con los diferentes componentes virtuales que lo integran (kcpsm.vhd, arithmetic_unit.vhd, lcd_interface.vhd, program_memory.vhd) y del archivo de asignación de pines (pins.ucf), procederemos a sintetizarlo e implementarlo en la FPGA. Para ello utilizaremos la aplicación Xilinx ISE Design Suite 11, con dos de sus programas, ISE Project Navigator para generar el archivo e iMPACT para grabarlo en la placa. Para mayor comodidad nuestra, uniremos en un solo archivo VHDL todos los componentes que conforman la Unidad Aritmética Decimal; este archivo será el blocks_uad.vhd. Por tanto, el listado de programas utilizado será el siguiente:

• blocks_uad.vhd • kcpsm.vhd • lcd_interface.vhd • main.vhd • pins.ucf • program_memory.vhd

Page 66: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 66 -

4.9.1 Generación del archivo Abrimos el programa ISE Project Navigator y creamos un nuevo proyecto (New Project) y escogemos un nombre para él. El siguiente paso es seleccionar las características del dispositivo que estamos utilizando, que en nuestro caso serán las siguientes:

Figura 4.14. Características de la FPGA Añadimos los modelos VHDL y el archivo pins.ucf:

Figura 4.15. Archivos utilizados en el proyecto

Page 67: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 67 -

Y vemos el dispositivo y los archivos que dependen de él:

Figura 4.16. Jerarquía del sistema completo El primer paso consiste en sintetizar el modelo (Synthesize - XST); esto genera un reporte que indica los recursos necesarios estimados para el dispositivo:

Tabla 4.5. Utilización del dispositivo Ahora realizamos la implementación (Implement Design), el Placement & Routing, que nos da una descripción concreta de los recursos necesarios de la FPGA para grabar nuestro diseño:

Tabla 4.6. Utilización del dispositivo

Page 68: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 68 -

El siguiente paso consiste en generar el archivo de programación (Generate Programming File). Ya tenemos creado nuestro archivo main.bit que será el que bajemos a la placa. 4.9.2 Implementación en la FPGA Grabaremos nuestro diseño (archivo main.bit) a través del puerto USB de la Spartan-3E. Desde Configure Target Device, seleccionamos Manage Configuration Project (iMPACT), los que nos llevará a la aplicación iMPACT. A través de Boundary Scan, buscamos el dispositivo (Initialize Chain) y se muestra en pantalla:

Figura 4.17. Componentes disponibles de la FPGA El componente xc3s500e corresponde a la FPGA y es donde programaremos nuestro diseño. Los otros dos componentes pertenecen a la memoria Platform Flash y al CPLD que hay integrados en la placa. Asignamos el archivo main.bit a la FPGA y los otros dos componentes los dejamos como están (Bypass). Ejecutamos Program en xc3s500e y ya tenemos la unidad operativa (el led DONE de la placa se enciende indicando que el proceso de implementación se ha completado correctamente).

Figura 4.18. FPGA disponible para su utilización

Page 69: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Memoria experimental

- 69 -

A continuación se muestran unas ilustraciones con ejemplos de las diferentes operaciones, siendo los operandos x = 2867335 e y = 50299723:

• Suma: el resultado es 53167058.

Figura 4.19. Resultado de la suma

• Resta: el resultado es – 47432388. Es negativo porque el dígito z8 (según la Figura 4.1) es 1.

Figura 4.20. Resultado de la resta

• Multiplicación: el resultado es 144226156248205.

Figura 4.21. Resultado de la multiplicación

• División: el resultado se ha de interpretar como 0.0570049858922682.

Figura 4.22. Resultado de la división

Page 70: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal

5. ANEXOS

Page 71: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 71 -

5.1 Modelos VHDL......................................................................................................................... 72

5.1.1 Sumador de 1 dígito BCD (one_digit_adder.vhd)............................................................ 72

5.1.2 Complemento a 9 (nine_complement.vhd) ....................................................................... 73

5.1.3 Sumador/Restador de n dígitos decimales (n_adder_subs.vhd) ....................................... 73

5.1.4 Multiplicador de 1x1 dígitos BCD (one_digit_multiplier.vhd) ........................................ 75

5.1.5 Multiplicador de Nx1 dígitos BCD (n_by_one_multiplier.vhd) ....................................... 76

5.1.6 Multiplicador de NxM dígitos BCD (n_by_m_multiplier.vhd) ........................................ 78

5.1.7 Divisor BCD (divider.vhd) ............................................................................................... 80

5.1.8 Unidad Aritmética Decimal (arithmetic_unit.vhd) ........................................................... 83

5.1.9 Memoria de programa (program_memory.vhd) ............................................................... 86

5.1.10 Circuito completo (main.vhd) ......................................................................................... 89

5.2 Programa en lenguaje ensamblador (decimal_unit.asm) ...................................................... 94

5.3 Asignación de pines en la Spartan-3E (pins.ucf) .................................................................... 97

Page 72: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 72 -

5.1 Modelos VHDL A continuación se detallan los diferentes modelos VHDL creados en los apartados anteriores. 5.1.1 Sumador de 1 dígito BCD (one_digit_adder.vhd) ---------------------------------------------------------------------- --Entidad del sumador de 1 dígito decimal ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY one_digit_adder IS PORT( a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); c: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); cy_in: IN STD_LOGIC; --carry de entrada al bloque cy_out: INOUT STD_LOGIC); --carry de salida del bloque END one_digit_adder; ---------------------------------------------------------------------- --Arquitectura del sumador de 1 dígito decimal ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_oda OF one_digit_adder IS --Declaración de señales SIGNAL d: STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL correction: STD_LOGIC_VECTOR(3 DOWNTO 0); --Inicio BEGIN d <= '0' & a + b + cy_in; cy_out <= d(4) OR (d(3) AND (d(2) OR d(1))); --crea carry de salida --si d>9 correction <= '0' & cy_out & cy_out & '0'; --se pone a '0110' si hay --carry de salida c <= d(3 DOWNTO 0) + correction; --aplica la corrección si --hay carry de salida END architecture_oda;

Page 73: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 73 -

5.1.2 Complemento a 9 (nine_complement.vhd) ---------------------------------------------------------------------- --Entidad del bloque de complemento a 9 ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY nine_complement IS PORT( e: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --dígito de entrada add_sub: IN STD_LOGIC; --señal de control del bloque s: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --dígito de salida END nine_complement; ---------------------------------------------------------------------- --Arquitectura del bloque de complemento a 9 ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_nc OF nine_complement IS BEGIN s(0) <= (NOT(add_sub) AND e(0)) OR (add_sub AND NOT(e(0))); s(1) <= e(1); s(2) <= (NOT(add_sub) AND e(2)) OR (add_sub AND (e(1) XOR e(2))); s(3) <= (NOT(add_sub) AND e(3)) OR (add_sub AND (NOT(e(1)) AND NOT(e(2)) AND NOT(e(3)))); END architecture_nc; 5.1.3 Sumador/Restador de n dígitos decimales (n_adder_subs.vhd) ---------------------------------------------------------------------- --Entidad del sumador/restador de n dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY n_adder_subs IS GENERIC (n:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD add_sub: IN STD_LOGIC; --operación: '0' suma y '1' resta z: OUT STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --salida de n dígitos BCD carry_out: OUT STD_LOGIC); --acarreo de salida END n_adder_subs;

Page 74: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 74 -

---------------------------------------------------------------------- --Arquitectura del sumador/restador de n dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_nas OF n_adder_subs IS --Declaración de constantes CONSTANT i1: STD_LOGIC_VECTOR(4*n-1 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(1,4*n); --Declaración de señales SIGNAL carries,carries2: STD_LOGIC_VECTOR(n DOWNTO 0); SIGNAL y1: STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); SIGNAL z1,z2,z3: STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); SIGNAL oc, output_selection: STD_LOGIC; --Declaración de componentes COMPONENT one_digit_adder IS PORT( a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); c: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); cy_in: IN STD_LOGIC; --carry de entrada al bloque cy_out: INOUT STD_LOGIC); --carry de salida del bloque END COMPONENT; COMPONENT nine_complement PORT( --bloque que complementa a 9 e: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --dígito de entrada add_sub: IN STD_LOGIC; --señal de control del bloque s: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --dígito de salida END COMPONENT; --Inicio BEGIN carries(0) <= add_sub; a1_iteration: FOR i IN 0 TO n-1 GENERATE --Complemento a 9 de 'y' nine_compl: nine_complement PORT MAP( --en función de 'add_sub' e => y(4*i+3 DOWNTO 4*i), add_sub => add_sub, s => y1(4*i+3 DOWNTO 4*i)); END GENERATE; a2_iteration: FOR i IN 0 TO n-1 GENERATE addition: one_digit_adder PORT MAP( a => x(4*i+3 DOWNTO 4*i), b => y1(4*i+3 DOWNTO 4*i), c => z1(4*i+3 DOWNTO 4*i), cy_in => carries(i), cy_out => carries(i+1)); END GENERATE; oc <= carries(n); --señal que utilizamos si el carry de --de salida es 0, resultado negativo

Page 75: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 75 -

b1_iteration: FOR i IN 0 TO n-1 GENERATE --bloque que complementa a 9 nine_compl_2: nine_complement PORT MAP( --cuando el resultado e => z1(4*i+3 DOWNTO 4*i), --anterior sea negativo add_sub => add_sub, s => z2(4*i+3 DOWNTO 4*i)); END GENERATE; carries2(0) <= '0'; b2_iteration: FOR i IN 0 TO n-1 GENERATE --bloque utilizado para addition_2: one_digit_adder PORT MAP( --sumar 1 en BCD al a => z2(4*i+3 DOWNTO 4*i), --complemento a nueve b => i1(4*i+3 DOWNTO 4*i), --generado antes c => z3(4*i+3 DOWNTO 4*i), cy_in => carries2(i), cy_out => carries2(i+1)); END GENERATE; output_selection <= add_sub AND NOT(oc); WITH output_selection SELECT z <= z3 WHEN '1', z1 WHEN OTHERS; carry_out <= oc XOR add_sub; --Si la operación es suma: carry_out = '0' => resultado exacto --Si la operación es suma: carry_out = '1' => hay desbordamiento, --añadir un '1' a la izquierda --Si la operación es resta: carry_out = '0' => resultado no negativo --Si la operación es resta: carry_out = '1' => resultado negativo END architecture_nas; 5.1.4 Multiplicador de 1x1 dígitos BCD (one_digit_multiplier.vhd) ---------------------------------------------------------------------- --Entidad del multiplicador de 1 dígito decimal ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY one_digit_multiplier IS PORT( a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --entrada de 1 dígito BCD b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --entrada de 1 dígito BCD d: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --salida de 1 dígito BCD u: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --salida de 1 dígito BCD END one_digit_multiplier; ---------------------------------------------------------------------- --Arquitectura del multiplicador de 1 dígito decimal ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_odm OF one_digit_multiplier IS

Page 76: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 76 -

--Declaración de señales SIGNAL p: STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL uu: STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL dd: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL gt9, gt20, gt10st19: STD_LOGIC; --Inicio BEGIN p <= a*b; --producto binario uu <= p(3 DOWNTO 0) + ("00"&p(4)&p(4)&'0') + ("00"&p(6 DOWNTO 5)&'0'); dd <= p(6 DOWNTO 4) + ("00"&p(6 DOWNTO 5)); gt9 <= uu(4) OR (uu(3) AND (uu(2) OR uu(1))); --mayor a 9 gt20 <= uu(4) AND (uu(3) OR uu(2)); --mayor a 19 gt10st19 <= gt9 AND NOT(gt20); --entre 10 y 19 d <= dd + ('0' & '0' & gt20 & gt10st19); u <= uu(3 DOWNTO 0) + (gt20 & gt9 & gt10st19 & '0'); END architecture_odm; 5.1.5 Multiplicador de Nx1 dígitos BCD (n_by_one_multiplier.vhd) ---------------------------------------------------------------------- --Entidad del multiplicador de Nx1 dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY n_by_one_multiplier IS GENERIC (n:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --entrada de 1 dígito BCD z: OUT STD_LOGIC_VECTOR(4*n+3 DOWNTO 0)); --salida de n dígitos BCD END n_by_one_multiplier; ---------------------------------------------------------------------- --Arquitectura del multiplicador de Nx1 dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_nbom OF n_by_one_multiplier IS --Declaración de señales SIGNAL dd,uu: STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); SIGNAL ddc,uuc: STD_LOGIC_VECTOR(4*n+3 DOWNTO 0); SIGNAL carries: STD_LOGIC_VECTOR(n+1 DOWNTO 0);

Page 77: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 77 -

--Declaración de componentes COMPONENT one_digit_multiplier IS PORT( a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --entrada de 1 dígito BCD b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --entrada de 1 dígito BCD d: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --salida de 1 dígito BCD u: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --salida de 1 dígito BCD END COMPONENT; COMPONENT one_digit_adder IS PORT( a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); c: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); cy_in: IN STD_LOGIC; --carry de entrada al bloque cy_out: INOUT STD_LOGIC); --carry de salida del bloque END COMPONENT; --Inicio BEGIN a_iteration: FOR i IN 0 TO n-1 GENERATE multiplier: one_digit_multiplier PORT MAP( a => x(4*i+3 DOWNTO 4*i), b => y, d => dd(4*i+3 DOWNTO 4*i), u => uu(4*i+3 DOWNTO 4*i)); END GENERATE; ddc <= dd & "0000"; uuc <= "0000" & uu; carries(0) <= '0'; b_iteration: FOR i IN 0 TO n GENERATE adder: one_digit_adder PORT MAP( a => ddc(4*i+3 DOWNTO 4*i), b => uuc(4*i+3 DOWNTO 4*i), c => z(4*i+3 DOWNTO 4*i), cy_in => carries(i), cy_out => carries(i+1)); END GENERATE; END architecture_nbom;

Page 78: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 78 -

5.1.6 Multiplicador de NxM dígitos BCD (n_by_m_multiplier.vhd) ---------------------------------------------------------------------- --Entidad del multiplicador de N x M dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY n_by_m_multiplier IS GENERIC (n,m:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(4*m-1 DOWNTO 0); --entrada de m dígitos BCD start: IN STD_LOGIC; --señal de inicio clk: IN STD_LOGIC; --señal de reloj reset: IN STD_LOGIC; --inicializa la operación z: INOUT STD_LOGIC_VECTOR(4*(n+m)-1 DOWNTO 0); --salida de N+M --dígitos BCD done: OUT STD_LOGIC); --resultado disponible END n_by_m_multiplier; ---------------------------------------------------------------------- --Arquitectura del multiplicador de N x M dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_nbmm OF n_by_m_multiplier IS --Declaración de estados TYPE states IS RANGE 0 TO 3; SIGNAL current_state: states; --Declaración de constantes CONSTANT initial_zeroes: STD_LOGIC_VECTOR(4*m-5 DOWNTO 0) := (OTHERS => '0'); --Declaración de señales SIGNAL int_y: STD_LOGIC_VECTOR(4*m+3 DOWNTO 0); --registro y --el registro z se declara en la entidad SIGNAL x_by_yi: STD_LOGIC_VECTOR(4*n+3 DOWNTO 0); SIGNAL next_z: STD_LOGIC_VECTOR(4*(n+m)-1 DOWNTO 0); SIGNAL z_by_10, long_x_by_yi: STD_LOGIC_VECTOR(4*(n+m)-1 DOWNTO 0); SIGNAL load, shift, end_of_computation: STD_LOGIC; --Declaración de componentes COMPONENT n_by_one_multiplier IS --multiplicador de Nx1 dígitos BCD GENERIC (n:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --entrada de 1 dígito BCD z: OUT STD_LOGIC_VECTOR(4*n+3 DOWNTO 0)); --salida de n dígitos BCD END COMPONENT;

Page 79: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 79 -

COMPONENT n_adder_subs IS --Sumador/restador utilizado para sumar GENERIC (n:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD add_sub: IN STD_LOGIC; --operación: '0' suma y '1' resta z: OUT STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --salida de n dígitos BCD carry_out: OUT STD_LOGIC); --acarreo de salida END COMPONENT; --Inicio BEGIN multiplier: n_by_one_multiplier GENERIC MAP(n => n) PORT MAP( x => x, y => int_y(4*m+3 DOWNTO 4*m), z => x_by_yi); long_x_by_yi <= initial_zeroes&x_by_yi; --equiparamos las dos entradas --del sumador en cuanto a --número de dígitos adder: n_adder_subs GENERIC MAP(n => n+m) PORT MAP( x => long_x_by_yi, y => z_by_10, add_sub => '0', --operación a realizar: suma z => next_z); z_by_10 <= z(4*(n+m)-5 DOWNTO 0)&"0000"; --multiplicamos z por 10 --Sentencias secuenciales register_y: PROCESS(clk) BEGIN IF clk'EVENT AND clk = '1' THEN IF load = '1' THEN int_y <= y & "1111"; ELSIF shift = '1' THEN int_y <= int_y(4*m-1 DOWNTO 0) & "0000"; END IF; END IF; END PROCESS; register_z: PROCESS(clk) BEGIN IF clk'EVENT AND clk = '1' THEN IF load = '1' THEN z <= (OTHERS => '0'); ELSIF shift = '1' THEN z <= next_z; END IF; END IF; END PROCESS; end_of_computation <= int_y(4*m+3) AND int_y(4*m+2);

Page 80: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 80 -

--Unidad de control control_unit_output: PROCESS(current_state, end_of_computation) BEGIN CASE current_state IS WHEN 0 to 1 => shift <= '0'; load <= '0'; done <= '1'; WHEN 2 => shift <= '0'; load <= '1'; done <= '0'; WHEN 3 => IF end_of_computation = '0' THEN shift <= '1'; ELSE shift <= '0'; END IF; load <= '0'; done <= '0'; END CASE; END PROCESS; control_unit_next_state: PROCESS(clk, reset) BEGIN IF reset = '1' THEN current_state <= 0; ELSIF clk'event AND clk = '1' THEN CASE current_state IS WHEN 0 => IF start = '0' THEN current_state <= 1; END IF; WHEN 1 => IF start = '1' THEN current_state <= 2; END IF; WHEN 2 => current_state <= 3; WHEN 3 => IF end_of_computation = '1' THEN current_state <= 0; END IF; END CASE; END IF; END PROCESS; END architecture_nbmm; 5.1.7 Divisor BCD (divider.vhd) ---------------------------------------------------------------------- --Entidad del divisor de n dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY decimal_divider IS GENERIC (n,m,p,logp:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --dividendo y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --divisor start: IN STD_LOGIC; --señal de inicio clk: IN STD_LOGIC; --señal de reloj reset: IN STD_LOGIC; --inicializa operación q: OUT STD_LOGIC_VECTOR(4*m-1 DOWNTO 0); --resultado (cociente) done: OUT STD_LOGIC); --operación realizada END decimal_divider;

Page 81: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 81 -

---------------------------------------------------------------------- --Arquitectura del divisor de n dígitos decimales ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_divider OF decimal_divider IS --Declaración de estados TYPE states IS RANGE 0 TO 3; SIGNAL current_state: states; --Declaración de constantes CONSTANT initial_zeroes: STD_LOGIC_VECTOR(4*p-9 DOWNTO 0) := ( OTHERS => '0'); CONSTANT initial_zeroes_2: STD_LOGIC_VECTOR(4*p-5 DOWNTO 0) := ( OTHERS => '0'); --Declaración de señales SIGNAL r, s1: STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); SIGNAL rr, rr_y, yy: STD_LOGIC_VECTOR(4*n+3 DOWNTO 0); SIGNAL qq, ulp, qq_ulp, s2: STD_LOGIC_VECTOR(4*p-1 DOWNTO 0); SIGNAL c_out: STD_LOGIC; SIGNAL load, ce, zero: STD_LOGIC; SIGNAL ulp_by_5: STD_LOGIC_VECTOR(4*p+3 DOWNTO 0); SIGNAL count: STD_LOGIC_VECTOR(logp-1 DOWNTO 0); --Declaración de componentes COMPONENT n_by_one_multiplier IS --multiplicador de Nx1 dígitos BCD GENERIC (n:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --entrada de 1 dígito BCD z: OUT STD_LOGIC_VECTOR(4*n+3 DOWNTO 0)); --salida de n dígitos BCD END COMPONENT; COMPONENT n_adder_subs IS --Sumador/restador utilizado para sumar GENERIC (n:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD add_sub: IN STD_LOGIC; --operación: '0' suma y '1' resta z: OUT STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --salida de n dígitos BCD carry_out: OUT STD_LOGIC); --acarreo de salida END COMPONENT; --Inicio BEGIN yy <= "0000" & y; --Añadimos un 0 decimal a 'y' para igualarla --en número de dígitos a rr (2r) multiplier_r_by_2: n_by_one_multiplier --Multiplicador de r x 2 GENERIC MAP(n => n) PORT MAP( x => r, y => "0010", --2 en decimal z => rr); --resultado 2r

Page 82: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 82 -

subtraction: n_adder_subs --Restador para realizar 2r - y GENERIC MAP(n => n+1) PORT MAP( x => rr, --2r y => yy, add_sub => '1', --Resta como operación a realizar z => rr_y, --resultado de 2r-y carry_out => c_out); WITH NOT(c_out) SELECT s1 <= rr(4*n-1 DOWNTO 0) WHEN '0', rr_y(4*n-1 DOWNTO 0) WHEN OTHERS; addition: n_adder_subs --Sumador para realizar qq + ulp GENERIC MAP(n => p) PORT MAP( x => qq, y => ulp, add_sub => '0', --Suma como operación a realizar z => qq_ulp); WITH NOT(c_out) SELECT s2 <= qq WHEN '0', qq_ulp WHEN OTHERS; multiplier_ulp_by_5: n_by_one_multiplier --Multiplicador de ulp x 5 GENERIC MAP(n => p) PORT MAP( x => ulp, y => "0101", --5 en BCD z => ulp_by_5); --resultado 5*ulp q <= qq(4*p-1 DOWNTO 4*(p-m)); --Los m dígitos más significativos --de qq --Sentencias secuenciales register_r: PROCESS(clk) BEGIN IF clk'EVENT AND clk = '1' THEN IF load = '1' THEN r <= x; --El valor inicial de r es x ELSIF ce = '1' THEN r <= s1; --Actualiza el valor de r END IF; END IF; END PROCESS; register_qq: PROCESS(clk) BEGIN IF clk'EVENT AND clk = '1' THEN IF load = '1' THEN qq <= (OTHERS => '0');--Valor inicial de qq es 0 ELSIF ce = '1' THEN qq <= s2; --Actualiza el valor de qq END IF; END IF; END PROCESS; register_ulp: PROCESS(clk) BEGIN IF clk'EVENT AND clk = '1' THEN IF load = '1' THEN ulp <= "0101" & initial_zeroes_2;

--El valor inicial es 5, que representa 0.5 ELSIF ce = '1' THEN ulp <= ulp_by_5(4*p+3 DOWNTO 4);--Actualiza ulp END IF; END IF; END PROCESS;

Page 83: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 83 -

--Contador de p estados counter_stages: PROCESS(clk) BEGIN IF clk'EVENT AND clk = '1' THEN IF load = '1' THEN count <= CONV_STD_LOGIC_VECTOR(p-1, logp); ELSIF ce = '1' THEN count <= count - 1; END IF; END IF; END PROCESS; zero <= '1' WHEN count = "0" ELSE '0'; --Unidad de control control_unit: PROCESS(clk, reset, current_state, zero) BEGIN CASE current_state IS WHEN 0 to 1 => load <= '0'; ce <= '0'; done <= '1'; WHEN 2 => load <= '1'; ce <= '0'; done <= '0'; WHEN 3 => load <= '0'; ce <= '1'; done <= '0'; END CASE; IF reset = '1' THEN current_state <= 0; ELSIF clk'EVENT AND clk = '1' THEN CASE current_state IS WHEN 0 => IF start = '0' THEN current_state <= 1; END IF; WHEN 1 => IF start = '1' THEN current_state <= 2; END IF; WHEN 2 => current_state <= 3; WHEN 3 => IF zero = '1' THEN current_state <= 0; END IF; END CASE; END IF; END PROCESS; END architecture_divider; 5.1.8 Unidad Aritmética Decimal (arithmetic_unit.vhd) ---------------------------------------------------------------------- --Entidad de la unidad aritmética decimal ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY arithmetic_unit IS GENERIC (n, p, logp: NATURAL); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --operando x y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --operando y operation: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --operación start: IN STD_LOGIC; --señal de inicio clk: IN STD_LOGIC; --señal de reloj reset: IN STD_LOGIC; --inicializa z: OUT STD_LOGIC_VECTOR(8*n-1 DOWNTO 0); --resultado done: OUT STD_LOGIC); --operación lista END arithmetic_unit;

Page 84: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 84 -

---------------------------------------------------------------------- --Arquitectura de la unidad aritmética decimal ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_au OF arithmetic_unit IS --Declaración de señales SIGNAL s1: STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); SIGNAL s2, s3: STD_LOGIC_VECTOR(8*n-1 DOWNTO 0); SIGNAL c_out, done1, done2: STD_LOGIC; SIGNAL start1, start2: STD_LOGIC; --Declaración de componentes COMPONENT n_adder_subs IS GENERIC (n:natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD add_sub: IN STD_LOGIC; --operación: '0' suma y '1' resta z: OUT STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --salida de n dígitos BCD carry_out: OUT STD_LOGIC); --acarreo de salida END COMPONENT; COMPONENT n_by_m_multiplier IS GENERIC (n, m: natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dígitos BCD y: IN STD_LOGIC_VECTOR(4*m-1 DOWNTO 0); --entrada de m dígitos BCD start: IN STD_LOGIC; --señal de inicio clk: IN STD_LOGIC; --señal de reloj reset: IN STD_LOGIC; --inicializa la operación z: INOUT STD_LOGIC_VECTOR(4*(n+m)-1 DOWNTO 0); --salida de N+M --dígitos BCD done: OUT STD_LOGIC); --resultado disponible END COMPONENT; COMPONENT decimal_divider IS GENERIC (n, m, p, logp: natural); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --dividendo y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --divisor start: IN STD_LOGIC; --señal de inicio clk: IN STD_LOGIC; --señal de reloj reset: IN STD_LOGIC; --inicializa operación q: OUT STD_LOGIC_VECTOR(4*m-1 DOWNTO 0); --resultado (cociente) done: OUT STD_LOGIC); --operación realizada END COMPONENT; --Inicio BEGIN start1 <= start AND NOT(operation(0)) AND operation(1); start2 <= start AND operation(0) AND operation(1);

Page 85: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 85 -

addition_substraction: n_adder_subs GENERIC MAP(n => n) PORT MAP( x => x, y => y, add_sub => operation(0), z => s1, carry_out => c_out); multiplier: n_by_m_multiplier GENERIC MAP(n => n, m => n) PORT MAP( x => x, y => y, start => start1, clk => clk, reset => reset, z => s2, done => done1); divider: decimal_divider GENERIC MAP(n => n, m => 2*n, p => p, logp => logp) PORT MAP( x => x, y => y, start => start2, clk => clk, reset => reset, q => s3, done => done2); WITH operation SELECT z(4*n-1 DOWNTO 0) <= s1 WHEN "00", s1 WHEN "01", s2(4*n-1 DOWNTO 0) WHEN "10", s3(4*n-1 DOWNTO 0) WHEN OTHERS; WITH operation SELECT z(8*n-1 DOWNTO 4*n) <= x"0000000" & "000" & c_out WHEN "00", x"0000000" & "000" & c_out WHEN "01", s2(8*n-1 DOWNTO 4*n) WHEN "10", s3(8*n-1 DOWNTO 4*n) WHEN OTHERS; WITH operation SELECT done <= '1' WHEN "00", '1' WHEN "01", done1 WHEN "10", done2 WHEN OTHERS; END architecture_au;

Page 86: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 86 -

5.1.9 Memoria de programa (program_memory.vhd) library IEEE ; use IEEE.STD_LOGIC_1164.all ; use IEEE.STD_LOGIC_ARITH.all ; use IEEE.STD_LOGIC_UNSIGNED.all ; library unisim ; use unisim.vcomponents.all ; entity program_memory is port ( clk : in std_logic ; reset : out std_logic ; address : in std_logic_vector( 7 downto 0 ) ; instruction : out std_logic_vector( 15 downto 0 ) ) ; end entity program_memory ; architecture mix of program_memory is component jtag_shifter is port ( clk : in std_logic ; user1 : out std_logic ; write : out std_logic ; addr : out std_logic_vector( 8 downto 0 ) ; data : out std_logic_vector( 7 downto 0 ) ) ; end component ; signal jaddr : std_logic_vector( 8 downto 0 ) ; signal jdata : std_logic_vector( 7 downto 0 ) ; signal juser1 : std_logic ; signal jwrite : std_logic ; attribute INIT_00 : string ; attribute INIT_01 : string ; attribute INIT_02 : string ; attribute INIT_03 : string ; attribute INIT_04 : string ; attribute INIT_05 : string ; attribute INIT_06 : string ; attribute INIT_07 : string ; attribute INIT_08 : string ; attribute INIT_09 : string ; attribute INIT_0A : string ; attribute INIT_0B : string ; attribute INIT_0C : string ; attribute INIT_0D : string ; attribute INIT_0E : string ; attribute INIT_0F : string ; attribute INIT_10 : string ; attribute INIT_11 : string ; attribute INIT_12 : string ; attribute INIT_13 : string ; attribute INIT_14 : string ; attribute INIT_15 : string ; attribute INIT_16 : string ; attribute INIT_17 : string ; attribute INIT_18 : string ; attribute INIT_19 : string ; attribute INIT_1A : string ; attribute INIT_1B : string ;

Page 87: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 87 -

attribute INIT_1C : string ; attribute INIT_1D : string ; attribute INIT_1E : string ; attribute INIT_1F : string ; attribute INIT_20 : string ; attribute INIT_21 : string ; attribute INIT_22 : string ; attribute INIT_23 : string ; attribute INIT_24 : string ; attribute INIT_25 : string ; attribute INIT_26 : string ; attribute INIT_27 : string ; attribute INIT_28 : string ; attribute INIT_29 : string ; attribute INIT_2A : string ; attribute INIT_2B : string ; attribute INIT_2C : string ; attribute INIT_2D : string ; attribute INIT_2E : string ; attribute INIT_2F : string ; attribute INIT_30 : string ; attribute INIT_31 : string ; attribute INIT_32 : string ; attribute INIT_33 : string ; attribute INIT_34 : string ; attribute INIT_35 : string ; attribute INIT_36 : string ; attribute INIT_37 : string ; attribute INIT_38 : string ; attribute INIT_39 : string ; attribute INIT_3A : string ; attribute INIT_3B : string ; attribute INIT_3C : string ; attribute INIT_3D : string ; attribute INIT_3E : string ; attribute INIT_3F : string ; attribute INITP_00 : string ; attribute INITP_01 : string ; attribute INITP_02 : string ; attribute INITP_03 : string ; attribute INITP_04 : string ; attribute INITP_05 : string ; attribute INITP_06 : string ; attribute INITP_07 : string ; attribute INIT_00 of bram : label is "8322E2130200832B9D0561018339834BF210A211832B010F8340038083400301" ; attribute INIT_01 of bram : label is "83228347E212E2130203832B83228347E212E2130202832B8322E2130201832B" ; attribute INIT_02 of bram : label is "6000A010952B6000A01080809D2561018339834BB210010F834003C08100832B" ; attribute INIT_03 of bram : label is "8080E0110000E0110002E2108335808091356000A01280809532640104FF912E" ; attribute INIT_04 of bram : label is "808042309D50600AC020808091476000A0138080E0110000E0110001E3108335" ; attribute INIT_05 of bram : label is "0000000000000000000000000000000000000000000000000000808042406209" ; attribute INIT_06 of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_07 of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ;

Page 88: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 88 -

attribute INIT_08 of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_09 of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_0A of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_0B of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_0C of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_0D of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_0E of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; attribute INIT_0F of bram : label is "0000000000000000000000000000000000000000000000000000000000000000" ; begin bram : component RAMB4_S8_S16 generic map ( INIT_00 => X"8322E2130200832B9D0561018339834BF210A211832B010F8340038083400301", INIT_01 => X"83228347E212E2130203832B83228347E212E2130202832B8322E2130201832B", INIT_02 => X"6000A010952B6000A01080809D2561018339834BB210010F834003C08100832B", INIT_03 => X"8080E0110000E0110002E2108335808091356000A01280809532640104FF912E", INIT_04 => X"808042309D50600AC020808091476000A0138080E0110000E0110001E3108335", INIT_05 => X"0000000000000000000000000000000000000000000000000000808042406209", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000" ) port map ( DIB => "0000000000000000", ENB => '1', WEB => '0', RSTB => '0', CLKB => clk, ADDRB => address, DOB => instruction( 15 downto 0 ),

Page 89: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 89 -

DIA => jdata( 7 downto 0 ), ENA => juser1, WEA => jwrite, RSTA => '0', CLKA => clk, ADDRA => jaddr, DOA => open ) ; jdata <= ( others => '0' ) ; jaddr <= ( others => '0' ) ; juser1 <= '0' ; jwrite <= '0' ; end architecture mix ; 5.1.10 Circuito completo (main.vhd) ---------------------------------------------------------------------- --Entidad del circuito completo ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY main IS PORT( data_in: IN STD_LOGIC_VECTOR(3 DOWNTO 0); ext_clk: IN STD_LOGIC; reset: IN STD_LOGIC; synch: IN STD_LOGIC; lcd_data: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); lcd_e: OUT STD_LOGIC; lcd_rs: OUT STD_LOGIC; lcd_rw: OUT STD_LOGIC); END main; ---------------------------------------------------------------------- --Arquitectura del circuito completo ---------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ARCHITECTURE architecture_main OF main IS --Declaración de componentes COMPONENT kcpsm IS PORT( --Procesador instruction: IN STD_LOGIC_VECTOR(15 DOWNTO 0); in_port: IN STD_LOGIC_VECTOR(7 DOWNTO 0); interrupt: IN STD_LOGIC; reset: IN STD_LOGIC; clk: IN STD_LOGIC; address: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); port_id: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); out_port: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); write_strobe: OUT STD_LOGIC; read_strobe: OUT STD_LOGIC); END COMPONENT;

Page 90: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 90 -

COMPONENT program_memory IS PORT( --Memoria de programa address: IN STD_LOGIC_VECTOR(7 DOWNTO 0); clk: IN STD_LOGIC; instruction: OUT STD_LOGIC_VECTOR(15 DOWNTO 0); reset: OUT STD_LOGIC); END COMPONENT; COMPONENT lcd_interface IS PORT( --Interfaz LCD temp_wr: IN STD_LOGIC_VECTOR(7 DOWNTO 0); reset: IN STD_LOGIC; clk: IN STD_LOGIC; i_write: IN STD_LOGIC; d_write: IN STD_LOGIC; lcd_data: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); lcd_e: OUT STD_LOGIC; lcd_rs: OUT STD_LOGIC; lcd_rw: OUT STD_LOGIC; ready: OUT STD_LOGIC); END COMPONENT; COMPONENT arithmetic_unit IS --Unidad aritmética decimal GENERIC (n, p, logp: NATURAL); PORT( x: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --operando x y: IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --operando y operation: IN STD_LOGIC_VECTOR(1 DOWNTO 0); --operación start: IN STD_LOGIC; --señal de inicio clk: IN STD_LOGIC; --señal de reloj reset: IN STD_LOGIC; --inicializa z: OUT STD_LOGIC_VECTOR(8*n-1 DOWNTO 0); --resultado done: OUT STD_LOGIC); --operación lista END COMPONENT; --Declaración de señales SIGNAL port_id, in_port: STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL mult_out: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL ready, done: STD_LOGIC; SIGNAL instruction: STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL address, out_port: STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL interrupt, write_strobe, read_strobe: STD_LOGIC; SIGNAL temp_wr: STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL i_write, d_write: STD_LOGIC; SIGNAL id_write: STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL x, y: STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL operation: STD_LOGIC_VECTOR(1 DOWNTO 0); SIGNAL z: STD_LOGIC_VECTOR(63 DOWNTO 0); SIGNAL start_op: STD_LOGIC; SIGNAL clk_2, clk_4, clk_8, clk: STD_LOGIC;

Page 91: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 91 -

--Inicio BEGIN WITH port_id SELECT in_port <= ("0000000"&synch) when "00010000", ("0000"&data_in) when "00010001", ("0000000"&ready) when "00010010", ("0000000"&done) when "00010011", ("0000"&mult_out) when others; processor: kcpsm PORT MAP( instruction, in_port, interrupt, reset, clk, address, port_id, out_port, write_strobe, read_strobe); memory: program_memory PORT MAP( address => address, clk => clk, instruction => instruction); output_interface: lcd_interface PORT MAP( temp_wr, reset, clk, i_write, d_write, lcd_data, lcd_e, lcd_rs, lcd_rw, ready); --Divisor de frecuencia PROCESS(ext_clk) BEGIN IF reset = '1' THEN clk_2 <= '0'; ELSIF ext_clk'EVENT AND ext_clk = '1' THEN clk_2 <= NOT(clk_2); END IF; END PROCESS; PROCESS(clk_2) BEGIN IF reset = '1' THEN clk_4 <= '0'; ELSIF clk_2'EVENT AND clk_2 = '1' THEN clk_4 <= NOT(clk_4); END IF; END PROCESS; PROCESS(clk_4) BEGIN IF reset = '1' THEN clk_8 <= '0'; ELSIF clk_4'EVENT AND clk_4 = '1' THEN clk_8 <= NOT(clk_8); END IF; END PROCESS; PROCESS(clk_8) BEGIN IF reset = '1' THEN clk <= '0'; ELSIF clk_8'EVENT AND clk_8 = '1' THEN clk <= NOT(clk); END IF; END PROCESS; --Registros register_temp_wr: PROCESS(clk) BEGIN IF clk'event AND clk = '0' THEN IF port_id = "00010000" AND write_strobe = '1' THEN temp_wr <= out_port; END IF; END IF; END PROCESS;

Page 92: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 92 -

register_id_write: PROCESS(clk) BEGIN IF clk'event AND clk = '0' THEN IF reset = '1' THEN id_write <= "00"; ELSIF port_id = "00010001" AND write_strobe = '1' THEN id_write <= out_port(1 DOWNTO 0); END IF; END IF; END PROCESS; i_write <= id_write(0); d_write <= id_write(1); register_x: PROCESS(clk) BEGIN IF clk'event AND clk = '0' THEN IF port_id = "00001000" AND write_strobe = '1' THEN x(3 DOWNTO 0) <= out_port(3 DOWNTO 0); ELSIF port_id = "00001001" AND write_strobe = '1' THEN x(7 DOWNTO 4) <= out_port(3 DOWNTO 0); ELSIF port_id = "00001010" AND write_strobe = '1' THEN x(11 DOWNTO 8) <= out_port(3 DOWNTO 0); ELSIF port_id = "00001011" AND write_strobe = '1' THEN x(15 DOWNTO 12) <= out_port(3 DOWNTO 0); ELSIF port_id = "00001100" AND write_strobe = '1' THEN x(19 DOWNTO 16) <= out_port(3 DOWNTO 0); ELSIF port_id = "00001101" AND write_strobe = '1' THEN x(23 DOWNTO 20) <= out_port(3 DOWNTO 0); ELSIF port_id = "00001110" AND write_strobe = '1' THEN x(27 DOWNTO 24) <= out_port(3 DOWNTO 0); ELSIF port_id = "00001111" AND write_strobe = '1' THEN x(31 DOWNTO 28) <= out_port(3 DOWNTO 0); END IF; END IF; END PROCESS; register_y: PROCESS(clk) BEGIN IF clk'event AND clk = '0' THEN IF port_id = "00000000" AND write_strobe = '1' THEN y(3 DOWNTO 0) <= out_port(3 DOWNTO 0); ELSIF port_id = "00000001" AND write_strobe = '1' THEN y(7 DOWNTO 4) <= out_port(3 DOWNTO 0); ELSIF port_id = "00000010" AND write_strobe = '1' THEN y(11 DOWNTO 8) <= out_port(3 DOWNTO 0); ELSIF port_id = "00000011" AND write_strobe = '1' THEN y(15 DOWNTO 12) <= out_port(3 DOWNTO 0); ELSIF port_id = "00000100" AND write_strobe = '1' THEN y(19 DOWNTO 16) <= out_port(3 DOWNTO 0); ELSIF port_id = "00000101" AND write_strobe = '1' THEN y(23 DOWNTO 20) <= out_port(3 DOWNTO 0); ELSIF port_id = "00000110" AND write_strobe = '1' THEN y(27 DOWNTO 24) <= out_port(3 DOWNTO 0); ELSIF port_id = "00000111" AND write_strobe = '1' THEN y(31 DOWNTO 28) <= out_port(3 DOWNTO 0); END IF; END IF; END PROCESS;

Page 93: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 93 -

register_operation: PROCESS(clk) BEGIN IF clk'event AND clk = '0' THEN IF port_id = "00010011" AND write_strobe = '1' THEN operation(1 DOWNTO 0) <= out_port(1 DOWNTO 0); END IF; END IF; END PROCESS; start_op <= '1' WHEN port_id = "00010010" AND write_strobe = '1' ELSE '0'; main_component: arithmetic_unit GENERIC MAP(n => 8, p => 56, logp => 6) PORT MAP( x => x, y => y, operation => operation, start => start_op, clk => clk, reset => reset, z => z, done => done); WITH port_id SELECT mult_out <= z(3 DOWNTO 0) WHEN "00000000", z(7 DOWNTO 4) WHEN "00000001", z(11 DOWNTO 8) WHEN "00000010", z(15 DOWNTO 12) WHEN "00000011", z(19 DOWNTO 16) WHEN "00000100", z(23 DOWNTO 20) WHEN "00000101", z(27 DOWNTO 24) WHEN "00000110", z(31 DOWNTO 28) WHEN "00000111", z(35 DOWNTO 32) WHEN "00001000", z(39 DOWNTO 36) WHEN "00001001", z(43 DOWNTO 40) WHEN "00001010", z(47 DOWNTO 44) WHEN "00001011", z(51 DOWNTO 48) WHEN "00001100", z(55 DOWNTO 52) WHEN "00001101", z(59 DOWNTO 56) WHEN "00001110", z(63 DOWNTO 60) WHEN OTHERS; interrupt <= '0'; END architecture_main;

Page 94: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 94 -

5.2 Programa en lenguaje ensamblador (decimal_unit.asm) VHDL "my_ROM_blank.vhd", "program_memory.vhd", "program_memory" ;direcciones de entrada z0 DSIN $00 z1 DSIN $01 z2 DSIN $02 z3 DSIN $03 z4 DSIN $04 z5 DSIN $05 z6 DSIN $06 z7 DSIN $07 z8 DSIN $08 z9 DSIN $09 z10 DSIN $0a z11 DSIN $0b z12 DSIN $0c z13 DSIN $0d z14 DSIN $0e z15 DSIN $0f synch DSIN $10 data_in DSIN $11 ready DSIN $12 done DSIN $13 ;direcciones de salida y0 DSOUT $00 y1 DSOUT $01 y2 DSOUT $02 y3 DSOUT $03 y4 DSOUT $04 y5 DSOUT $05 y6 DSOUT $06 y7 DSOUT $07 x0 DSOUT $08 x1 DSOUT $09 x2 DSOUT $0a x3 DSOUT $0b x4 DSOUT $0c x5 DSOUT $0d x6 DSOUT $0e x7 DSOUT $0f temp_wr DSOUT $10 id_write DSOUT $11 start DSOUT $12 operation DSOUT $13 ;registros internos acc EQU s0 address EQU s1 data EQU s2 command EQU s3 counter EQU s4

Page 95: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 95 -

;main program begin: load command, $01 call lcd_control ;send command 01 (clear) to display, ;borramos el display

load command, $80 call lcd_control ;send command 80 (cursor address = 00) to

;display, situamos el cursor al inicio de ;la primera fila

load address, $0f ;initial address = 15

first: ;escribimos los 16 dígitos de entrada, 8 ;para 'x' y 8 para 'y'

call wait_for_synch ;wait for a positive edge on synch in data, data_in ;store data_in in data out data, address ;write data into x(address) call encode_data ;data = ASCII code call lcd_data ;display character data sub address, $01 ;update address jump NC, first ;check whether address < 0 ;addition call wait_for_synch ;wait for a positive edge on synch load data, $00 out data, operation ;operation = 00 call display_z ;display x+y ;end of addition ;substraction call wait_for_synch ;wait for a positive edge on synch load data, $01 out data, operation ;operation = 01 call display_z ;display x-y ;end of substraction ;multiplication call wait_for_synch ;wait for a positive edge on synch load data, $02 out data, operation ;operation = 10 out data, start ;start computation call wait_for_done call display_z ;display x*y ;end of multiplication ;division call wait_for_synch ;wait for a positive edge on synch load data, $03 out data, operation ;operation = 11 out data, start ;start computation call wait_for_done call display_z ;display x/y ;end of division call wait_for_synch ;wait for a positive edge on synch jump begin ;end of main program

Page 96: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 96 -

;subroutines: ;display the result of the operation display_z: load command, $c0 call lcd_control ;send command c0 (cursor address = 40) to

;display load address, $0f ;initial address = 15 first_bis: in data, address ;read z(address) call encode_data ;data = ASCII code call lcd_data ;display character data sub address, $01 ;update address jump NC, first_bis ;check whether address < 0 ret ;wait for a positive edge on synch; acc is modified wait_for_synch: in acc, synch sub acc, $00 jump NZ, wait_for_synch wait_for_1: in acc, synch sub acc, $00 jump Z, wait_for_1 load counter, $ff update_counter: sub counter, $01 jump NZ, update_counter ret ;wait until ready is set; acc is modified wait_for_ready: in acc, ready sub acc, $00 jump Z, wait_for_ready ret ;lcd_data sends the character "data" to temp_wr and generates a ;two-cycle pulse on d_write; it clears "acc" lcd_data: call wait_for_ready ;wait fot lcd_interface ready out data, temp_wr ;send character to lcd load acc, $02 ;set d_write out acc, id_write load acc, $00 ;clear d_write out acc, id_write ret

Page 97: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Anexos

- 97 -

;lcd_controls sends the instruction "command" to temp_wr and generates a ;two-cycle pulse on i_write; it clears "acc" lcd_control: call wait_for_ready ;wait fot lcd_interface ready out command, temp_wr ;send instruction to lcd load acc, $01 ;set i_write out acc, id_write load acc, $00 ;clear i_write out acc, id_write ret ;wait until done is set; acc is modified wait_for_done: in acc, done sub acc, $00 jump Z, wait_for_done ret ;data = ASCII(data) encode_data: load acc, data sub acc, $0a jump NC, g_t_9 add data, $30 ret g_t_9: sub data, $09 add data, $40 ret 5.3 Asignación de pines en la Spartan-3E (pins.ucf) NET "ext_clk" LOC = "C9" | IOSTANDARD = LVCMOS33 ; NET "reset" LOC = "K17" | IOSTANDARD = LVTTL | PULLDOWN ; NET "data_in<3>" LOC = "N17" | IOSTANDARD = LVTTL | PULLUP ; NET "data_in<2>" LOC = "H18" | IOSTANDARD = LVTTL | PULLUP ; NET "data_in<1>" LOC = "L14" | IOSTANDARD = LVTTL | PULLUP ; NET "data_in<0>" LOC = "L13" | IOSTANDARD = LVTTL | PULLUP ; NET "synch" LOC = "D18" | IOSTANDARD = LVTTL | PULLDOWN ; NET "lcd_e" LOC = "M18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; NET "lcd_rs" LOC = "L18" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; NET "lcd_rw" LOC = "L17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; NET "lcd_data<3>" LOC = "M15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; NET "lcd_data<2>" LOC = "P17" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; NET "lcd_data<1>" LOC = "R16" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ; NET "lcd_data<0>" LOC = "R15" | IOSTANDARD = LVCMOS33 | DRIVE = 4 | SLEW = SLOW ;

Page 98: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal

6. BIBLIOGRAFÍA

Page 99: Diseño sobre FPGA de una Unidad Aritmética Decimaldeeea.urv.cat/public/PROPOSTES/pub/pdf/1453pub.pdfDiseño sobre FPGA de una Unidad Aritmética Decimal Índice general - 4 - 4.

Diseño sobre FPGA de una Unidad Aritmética Decimal Bibliografía

- 99 -

6. Bibliografía [1] Serafín Alfonso Pérez, Enrique Soto, Santiago Fernández, “Diseño de Sistemas Digitales con VDHL”,

Editorial Thomson, 2002.

[2] Fernando Pardo Carpio, José A. Boluda Grau, “VHDL: Lenguaje para síntesis y modelado de circuitos”, Editorial Ra-Ma, 1999.

[3] John F. Wakerly, “Diseño digital. Principios y prácticas”, Tercera edición, Editorial Prentice Hall, 2001.

[4] Thomas L. Floyd, “Fundamentos de sistemas digitales”, Novena edición, Editorial Prentice Hall, 2006.

[5] M. Vazquez, G. Sutter, G. Bioul, J.-P. Deschamps, “Decimal adders/substractors in FPGA: Efficient 6-input LUT implementations”.

[6] J.-P. Deschamps, G. Sutter, G. Bioul, M. Vazquez, “Decimal division: algorithms and FPGA implementations”.

[7] G. Sutter, E. Todorovich, G. Bioul, M. Vazquez, J.-P. Deschamps, “FPGA Implementations of BCD Multipliers”.

[8] Electrónica Digital I, apuntes de la asignatura.

[9] ModelSim User’s Manual Software Version 6.5ª, Mentor Graphics, 2009.

[10] Spartan-3E FPGA Starter Kit Board User Guide, UG230 (v1.1), Xilinx, 2008.

[11] Spartan-3E FPGA Family: Functional Description, DS312-2 (v1.0), Xilinx, 2005.

[12] PicoBlaze 8-Bit Microcontroller for Virtex-E and Spartan-II/IIE Devices, XAPP213 (v2.1), Xilinx, 2003.

[13] http://www.model.com/

[14] http://www.xilinx.com/