Вы находитесь на странице: 1из 99

Diseo sobre FPGA de una Unidad Aritmtica Decimal

TITULACIN: Ingeniera Tcnica Industrial en Electrnica Industrial

AUTOR: Alejandro Baena Alonso


DIRECTOR: Jean-Pierre Deschamps
FECHA: Febrero / 2010

Diseo sobre FPGA de una Unidad Aritmtica Decimal

1. NDICE GENERAL

Diseo sobre FPGA de una Unidad Aritmtica Decimal

ndice general

2. INTRODUCCIN
2.1 Objetivos del proyecto ............................................................................................................... 7
2.2 Aspectos bsicos ......................................................................................................................... 7
2.2.1 Aritmtica decimal.............................................................................................................. 7
2.2.2 Cdigo decimal codificado en binario (BCD) .................................................................... 8
2.2.3 Dispositivos programables.................................................................................................. 8
2.3 Diseo de Sistemas Electrnicos ............................................................................................... 9
2.3.1 Tendencias generales en Diseo Electrnico...................................................................... 9
2.3.2 Lenguajes de descripcin del hardware .............................................................................. 9
2.3.2.1 Qu son los lenguajes de descripcin del hardware?............................................. 9
2.3.2.2 El lenguaje VHDL ................................................................................................... 10
2.3.2.2.1 Introduccin al lenguaje VHDL .................................................................... 10
2.3.2.2.2 Caractersticas............................................................................................... 10
2.3.2.2.3 Niveles de descripcin ................................................................................... 11
2.3.2.2.4 Estructura de una descripcin....................................................................... 11
2.3.2.2.5 Metodologa de diseo................................................................................... 12
2.3.3 Dispositivos lgicos programables ................................................................................... 13
2.3.4 Componentes IP (IP cores)............................................................................................... 15
2.3.5 Prototipado rpido ............................................................................................................ 16
2.4 Spartan-3E Starter Kit Board ................................................................................................... 16
3. MEMORIA DESCRIPTIVA
3.1 La Unidad Aritmtica 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 dgito BCD (bloque one_digit_adder.vhd)......................... 21
3.2.1.1.2 Sumador de n dgitos decimales .................................................................... 24
3.2.1.2 Restador............................................................................................................... 26
3.2.1.2.1 Clculo 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, representacin con signo y magnitud (bloque
n_adder_subs.vhd).......................................................................................................... 29
3.2.2 Multiplicador.. .......................................................................................................... 32
3.2.2.1 Multiplicador de 1x1 dgitos BCD (bloque one_digit_multiplier.vhd)................ 32
3.2.2.2 Multiplicador de Nx1 dgitos BCD (bloquen_by_one_multiplier.vhd)............... 34
3.2.2.3 Multiplicador de NxM dgitos BCD (bloquen_by_m_multiplier.vhd) ................ 37
3.2.3 Divisor .............................................................................................................................. 41
3.2.3.1 Algoritmo de divisin binaria ................................................................................. 41
3.2.3.2 Algoritmo de divisin BCD ..................................................................................... 42
3.2.3.3 Error generado........................................................................................................ 42
3.2.3.4 Divisor BCD (bloque divider.vhd)...................................................................... 43
3.3 Diseo de la Unidad Aritmtica Decimal ............................................................................... 48

-3-

Diseo sobre FPGA de una Unidad Aritmtica Decimal

ndice general

4. MEMORIA EXPERIMENTAL
4.1 Descripcin del proceso ...........................................................................................................
4.2 Especificaciones ........................................................................................................................
4.3 Elementos necesarios................................................................................................................
4.4 Arquitectura a desarrollar ......................................................................................................
4.5 Mdulos IP de terceros utilizados...........................................................................................
4.5.1 Microcontrolador PicoBlaze (mdulo kcpsm.vhd)........................................................
4.5.2 Interfaz LCD (mdulo lcd_interface.vhd).....................................................................
4.6 Memoria de programa (mdulo program_memory.vhd) ...................................................
4.7 Generacin del circuito (mdulo main.vhd) .......................................................................
4.8 Asignacin de pines en la FPGA (archivo pins.ucf) ..........................................................
4.9 Implementacin en la FPGA ...................................................................................................
4.9.1 Generacin del archivo .....................................................................................................
4.9.2 Implementacin en la FPGA ............................................................................................

54
54
55
55
57
57
58
60
62
63
65
66
68

5. ANEXOS
5.1 Modelos VHDL.........................................................................................................................
5.1.1 Sumador de 1 dgito BCD (one_digit_adder.vhd)............................................................
5.1.2 Complemento a 9 (nine_complement.vhd) .......................................................................
5.1.3 Sumador/Restador de n dgitos decimales (n_adder_subs.vhd) .......................................
5.1.4 Multiplicador de 1x1 dgitos BCD (one_digit_multiplier.vhd) ........................................
5.1.5 Multiplicador de Nx1 dgitos BCD (n_by_one_multiplier.vhd) .......................................
5.1.6 Multiplicador de NxM dgitos BCD (n_by_m_multiplier.vhd).........................................
5.1.7 Divisor BCD (divider.vhd) ...............................................................................................
5.1.8 Unidad Aritmtica Decimal (arithmetic_unit.vhd) ...........................................................
5.1.9 Memoria de programa (program_memory.vhd) ...............................................................
5.1.10 Circuito completo (main.vhd) .........................................................................................
5.2 Programa en lenguaje ensamblador (decimal_unit.asm) ......................................................
5.3 Asignacin de pines en la Spartan-3E (pins.ucf) ....................................................................

72
72
73
73
75
76
78
80
83
86
89
94
97

6. BIBLIOGRAFA........................................................................................................................ 99

-4-

Diseo sobre FPGA de una Unidad Aritmtica Decimal

2. INTRODUCCIN

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

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


2.2 Aspectos bsicos ......................................................................................................................... 7
2.2.1 Aritmtica decimal.............................................................................................................. 7
2.2.2 Cdigo decimal codificado en binario (BCD) .................................................................... 8
2.2.3 Dispositivos programables.................................................................................................. 8
2.3 Diseo de Sistemas Electrnicos ............................................................................................... 9
2.3.1 Tendencias generales en Diseo Electrnico...................................................................... 9
2.3.2 Lenguajes de descripcin del hardware .............................................................................. 9
2.3.2.1 Qu son los lenguajes de descripcin del hardware?............................................. 9
2.3.2.2 El lenguaje VHDL ................................................................................................... 10
2.3.2.2.1 Introduccin al lenguaje VHDL .................................................................... 10
2.3.2.2.2 Caractersticas............................................................................................... 10
2.3.2.2.3 Niveles de descripcin ................................................................................... 11
2.3.2.2.4 Estructura de una descripcin....................................................................... 11
2.3.2.2.5 Metodologa de diseo................................................................................... 12
2.3.3 Dispositivos lgicos programables ................................................................................... 13
2.3.4 Componentes IP (IP cores)............................................................................................... 15
2.3.5 Prototipado rpido ............................................................................................................ 16
2.4 Spartan-3E Starter Kit Board ................................................................................................... 16

-6-

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

2.1 Objetivos del proyecto


El objetivo de este proyecto es el diseo del modelo VHDL de una Unidad Aritmtica
Decimal, que pueda funcionar como coprocesador/acelerador dentro de otro sistema ms
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 aritmticas bsicas siempre operando en
decimal como son la suma, resta, multiplicacin y divisin 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 creacin y simulacin de la unidad aritmtica decimal se ha utilizado el programa
MODELSIM PE en su versin STUDENT EDITION. Para la implementacin en la FPGA,
se ha utilizado el ensamblador PBLAZ IDE para la creacin de la memoria de programa, y
el paquete ISE DESIGN SUITE de XILINX para la sntesis y grabacin del cdigo en la
placa de pruebas.

2.2 Aspectos bsicos


2.2.1 Aritmtica decimal
Los sistemas que operan en decimal son preferibles a los que lo hacen en binario en un
gran nmero de aplicaciones aritmticas informticas. El motivo principal no es la
complejidad de las interfaces de codificacin y decodificacin (que tambin influye), sino
principalmente la falta de precisin y claridad de los resultados.
La aritmtica decimal desempea 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
propsito general que incluyen la implementacin hardware de aritmtica decimal estn
adquiriendo relevancia
Actualmente, el sistema decimal codificado en binario (BCD) es utilizado en el diseo de
algoritmos de aritmtica decimal; aunque otros sistemas de codificacin podran resultar
interesantes, el sistema BCD parece la mejor opcin por el momento.

-7-

Introduccin

Diseo sobre FPGA de una Unidad Aritmtica Decimal

2.2.2 Cdigo decimal codificado en binario (BCD)


El cdigo decimal codificado en binario (BCD, Binary Coded Decimal, tambin conocido
como cdigo 8421) codifica los dgitos decimales del 0 al 9 mediante sus representaciones
binarias sin signo de 4 bits, desde 0000 a 1001. Las palabras de cdigo restantes, de 1010 a
1111, no se utilizan. Las conversiones entre las representaciones BCD y decimal son
triviales e implican la sustitucin directa de cuatro bits por cada dgito decimal.
El decimal codificado en binario es un cdigo ponderado, puesto que cada dgito decimal
puede obtenerse a partir de su palabra de cdigo asignando un peso fijo a cada bit de
palabra de cdigo. Los pesos para los bits BCD son 8, 4, 2, 1, y por esta razn el cdigo se
denomina en ocasiones cdigo 8421.
En la siguiente tabla se representa la correspondencia entre los nmeros decimales y las
combinaciones binarias del cdigo BCD:
Decimal

BCD

0
1
2
3
4
5
6
7
8
9

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001

Tabla 2.1. Correspondencia entre los dgitos decimales y cdigo BCD

2.2.3 Dispositivos programables


Hoy en da, las FPGA (Field Programmable Gate Arrays, de las que se hablar ms
adelante) son una de las tecnologas disponibles para el desarrollo de sistemas electrnicos.
Representan una atractiva opcin para la produccin de pequeas cantidades ya que sus
costes fijos (coste del prototipo, de la primera unidad) son bastante ms bajos que los
correspondientes en ASIC (Application-Specific Integrated Circuit, circuitos integrados de
aplicacin especfica). Adems, en pos de reducir el tamao y por tanto el coste unitario,
una posibilidad interesante es reconfigurarlas mientras operan de modo que el mismo
dispositivo pueda ejecutar diferentes funciones predefinidas.

-8-

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

2.3 Diseo de Sistemas Electrnicos


2.3.1 Tendencias generales en Diseo Electrnico
Actualmente los sistemas electrnicos estn muy presentes en la mayora de mbitos,
desde la electrnica de consumo a los sistemas de control industrial, pasando por las
aplicaciones para automocin o seguridad, y un largo etctera
El problema principal radica en la complejidad del diseo de muchos de los elementos,
donde se exige, por ejemplo, que sean de fcil utilizacin y adaptables a varias
aplicaciones, que consuman pocos recursos y que puedan estar rpidamente a la venta
La tecnologa 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 ms
microprocesadores o microcontroladores, coprocesadores, diversos bloques de memoria de
diferentes tipos, perifricos de entrada-salida, osciladores, buses para interconectar los
bloques, etc.
Estos sistemas embebidos para aplicaciones especficas incluyen hardware y software
especfico. En el caso de las FPGA, al ser dispositivos reconfigurables, son altamente tiles
para el desarrollo de prototipos o pequeas cantidades, a un precio razonablemente bajo.

2.3.2 Lenguajes de descripcin del hardware


2.3.2.1 Qu son los lenguajes de descripcin del hardware?
Los lenguajes de descripcin hardware (HDL, Hardware Description Language) surgen de
la necesidad de los diseadores de disponer de un conjunto de herramientas que permitan
describir los sistemas digitales de formas diferentes, facilitando el dilogo entre los propios
diseadores, aunque tambin entre las herramientas de diseo asistido por ordenador
(CAD, Computer-Aided Design) y entre diseadores y herramientas.
Los sistemas de desarrollo basados en lenguajes HDL permiten especificar y modelar la
estructura y funcin de un circuito digital; incluyen herramientas para compilar, simular y
sintetizar sistemas digitales. Estas herramientas de programacin se utilizan para
comprobar el funcionamiento del modelo antes de que sea construido.
Actualmente, los lenguajes HDL ms utilizados son VHDL y Verilog, ya que estn
estandarizados por el IEEE (Institute of Electrical and Electronic Engineers). Nosotros nos
centraremos en el primero de ellos.

-9-

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

2.3.2.2 El lenguaje VHDL


2.3.2.2.1 Introduccin al lenguaje VHDL
VHDL proviene de VHSIC (Very High Speed Integrated Circuit) Hardware Description
Language. VHDL es un lenguaje de descripcin del hardware que puede utilizarse para
modelar, documentar, simular, verificar y sintetizar un sistema digital. Por tanto, abarca el
ciclo completo de diseo (salvo el trazado fsico o layout) desde las especificaciones
iniciales hasta la construccin del prototipo hardware. Proporciona el soporte necesario
para especificar su comportamiento o estructura, incluyendo jerarquas. Asimismo, es til
para metodologas de diseo ascendentes (bottom-up) como, sobre todo, descendentes (topdown).
La semntica y construcciones del lenguaje permiten tambin disear con facilidad bancos
de prueba (test-benches), mediante los que se lleva a cabo la simulacin de los sistemas
modelados.

2.3.2.2.2 Caractersticas
VDHL es un lenguaje de descripcin 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 seales, variables,
constantes, etc., y proporciona amplias facilidades para la realizacin de algoritmos.
Admite casi todos los niveles de descripcin, desde el algortmico (nivel ms alto) hasta el
lgico (nivel ms bajo). Para ello proporciona herramientas semnticas y sintcticas que se
pueden agrupar as:

Aquellas orientadas a las descripciones del comportamiento del circuito.


Aquellas orientas a la descripcin de las relaciones entre los distintos bloques
de un circuito, es decir, su estructura.

Al realizar una descripcin VHDL es importante elegir adecuadamente el nivel de funcin


del objetivo perseguido. Por ejemplo, si se pretende sintetizar la descripcin realizada, es
decir, si el objetivo final es obtener un conjunto de puertas e interconexiones, no se debe
emplear el nivel algortmico, pues en general las herramientas actuales de sntesis 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 rpida y eficaz.

- 10 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

2.3.2.2.3 Niveles de descripcin


El lenguaje VHDL presenta tres mtodos bsicos para describir un circuito digital por
software:

El nivel algortmico es el que presenta un mayor grado de abstraccin (alto nivel).


Aqu el diseador solo describe el comportamiento del sistema, sin preocuparse de
las seales o componentes internos del mismo. Tambin llamado nivel de
comportamiento o behavior.

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


proporciona un cierto grado de abstraccin con respecto al hardware, pero el
diseador se ve obligado a describir las distintas seales que interactan en un
circuito y su comportamiento en funcin de las entradas por medio de ecuaciones
lgicas y sentencias de asignacin. Tambin conocido como nivel de flujo de datos.

El nivel lgico describe la estructura interna de un circuito basndose en unos


componentes bsicos definidos previamente (equivaldra a un diagrama lgico).

2.3.2.2.4 Estructura de una descripcin


Toda descripcin en VHDL est constituida al menos por tres tipos de elementos:
bibliotecas (libraries), entidades (entities) y arquitecturas (architectures).
El diseador generalmente realiza la descripcin de las entidades empleando elementos
almacenados en las bibliotecas.
En la declaracin de la entidad se define el diseo como si fuera un producto encapsulado,
indicando el nmero de pines, los puertos de entrada y salida. La entidad puede definir
bien las entradas y salidas de un circuito integrado por disear o puede definir la interfaz
de un mdulo que ser utilizado en un diseo ms grande.
Para que la descripcin de un circuito sea completa se necesita, adems de su declaracin
como entidad, una especificacin 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.

- 11 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

2.3.2.2.5 Metodologa de diseo


La Figura 2.1 muestra el flujo de diseo de un circuito en VHDL, desde su concepcin
hasta su fabricacin.

Figura 2.1. Flujo de diseo en VHDL

Una vez finalizada la prueba del concepto, se pasa al diseo detallado. Dependiendo de la
herramienta de sntesis que se utilice y de las especificaciones del circuito, la descripcin
VHDL estar desarrollada en un nivel de abstraccin mayor o menor (desde un nivel
algortmico a uno lgico).
Por ltimo se aborda la sntesis del circuito, es decir, el paso de una descripcin en VHDL
a un circuito real. El proceso de diseo puede terminar antes si el objetivo final no es la
fabricacin sino, por ejemplo, la creacin de componentes de biblioteca para uso posterior.

- 12 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

2.3.3 Dispositivos lgicos programables


Existen dos grandes grupos de dispositivos lgicos programables: PLDs (Programmable
Logic Device, dispositivo lgico programable) y FPGAs (Field Programmable Gate Array,
matriz de puertas configurables).

Figura 2.2. Tipos de lgica programable

Los PLDs estn 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
integracin de PLDs (PAL/GAL o PLA). Estn formados por bloques lgicos y matrices
de interruptores, donde cada bloque lgico corresponde a un PLD.

Figura 2.4. Ejemplo de arquitectura de CPLD (con 4 elementos lgicos o bloques programables)

- 13 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

Las FPGA estn compuestas por una matriz de elementos lgicos cuya interconexin y
funcionalidad se puede programar. En comparacin 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 tpica tiene un nmero de puertas equivalentes
mucho mayor que un dispositivo CPLD tpico. Los elementos que implementan las
funciones lgicas en las FPGA son, generalmente, mucho ms pequeos que en los CPLD,
por lo que hay muchos ms de esos elementos. Asimismo, en las FPGA, las
interconexiones programables estn organizadas segn una disposicin de filas y
columnas.

Figura 2.5. Arquitectura interna de una FPGA

Los tres elementos bsicos 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 homnimos en un CPLD, pero suele haber
muchos ms 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 permetro de las estructura proporcionan un acceso
de entrada/salida o bidireccional, individualmente seleccionable, hacia el mundo exterior.
Estructura de los bloques lgicos configurables
Cada bloque lgico de la FPGA est formado por mltiples mdulos lgicos ms pequeos
(que son los componentes bsicos) y por una serie de interconexiones programables locales
que se emplean para conectar entre s los mdulos lgicos que componen el CLB.
CLB
Mdulo lgico
Mdulo lgico
Interconexin
local

Mdulo lgico

Figura 2.6. Arquitectura de un CLB

- 14 -

Introduccin

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Un mdulo lgico puede configurarse para implementar lgica combinacional, lgica


registrada o una combinacin de ambas. Se emplea un flip-flop que forma parte de la lgica
asociada para implementar lgica registrada. A continuacin se muestra un diagrama de
bloques de un mdulo lgico tpico basado en LUT (Look-Up Table, tipo de memoria
programable que se utiliza para generar funciones booleanas):
Salida suma de
productos

A0
A1

Lgica
asociada

LUT

E/S

An-1

Mdulo lgico
Figura 2.7. Diagrama de bloques bsico de un mdulo lgico

Los dispositivos FPGA son reprogramables, y los de gran tamao pueden tener decenas de
miles de bloques CLB, adems de memoria y otros recursos. Por todo ello y la gran
flexibilidad que presentan, son ideales para realizar prototipos de manera rpida, en
pequeas 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 travs de terceros. Debido a
que estas funcionalidades son como componentes electrnicos, pero sin su parte fsica, 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 cdigo sintetizable, similar al cdigo


fuente para software o tambin a descripcin a nivel de puerta (netlist).
Entendemos por hard-core el caso de una descripcin fsica, a nivel fsico (de
transistores); estos mdulos presentan problemas a la hora de asociar diferentes
procesos entre ellos o pasar de una lnea de fabricacin a otra.
Por firm-core nos referimos a un diseo que puede ser modificado en trminos de
placement & routing o en tecnologa de bibliotecas.

Los dispositivos FPGA que contienen procesadores integrados y otras funciones


implementadas en forma de mdulos de hardware (hard-core) y de mdulos 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.

- 15 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Introduccin

2.3.5 Prototipado rpido


Un sistema completo (hardware y software) y su entorno no puede ser validado nicamente
mediante la simulacin. El objetivo es comprobar en la prctica el funcionamiento del
prototipo a un coste asequible.
El prototipado rpido es una posibilidad que facilita enormemente el diseo, mediante la
cual un circuito compuesto por una gran cantidad de puertas lgicas puede ser
implementado en un circuito integrado configurable, como lo puede ser una FPGA, a partir
de una descripcin en HDL mediante un simple ordenador personal (PC), sin la necesidad
de adquirir o disponer de un equipamiento caro. Y la tecnologa que permite dicha tcnica
la forman las tarjetas de prototipado rpido, que permiten reproducir desde funciones
sencillas hasta complejos sistemas en un chip (SoC, System on Chip).
Dichas tarjetas incluyen los componentes necesarios para esta misin: dispositivos
programables (CPLD, FPGA), memoria de datos y de programa, componentes de entradasalida y conectores (displays, puertos Ethernet, USB, RS-232, conversores analgicodigital 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 Aritmtica 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 alimentacin, cable USB para programar el dispositivo, software
para sintetizar e implementar nuestro modelo y manuales de referencia.
A continuacin enumeramos algunas caractersticas 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 lgicos configurables y 10000
celdas o mdulos lgicos)
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

- 16 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Interfaces y conectores:
-

4 interruptores tipo pulsador


4 salidas DAC (Digital-to-Analog Converter)
2 entradas ADC (Analog-to-Digital Converter)
Conexin Ethernet 10/100
Puerto USB
2 puertos serie RS-232
Puerto PS/2 para ratn o teclado
4 interruptores tipo slide

Display: Pantalla LCD de 2 lneas de 16 caracteres cada una

Figura 2.8. Vista superior de la Spartan-3E

- 17 -

Introduccin

Diseo sobre FPGA de una Unidad Aritmtica Decimal

3. MEMORIA DESCRIPTIVA

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.1 La Unidad Aritmtica 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 dgito BCD (bloque one_digit_adder.vhd)......................... 21
3.2.1.1.2 Sumador de n dgitos decimales .................................................................... 24
3.2.1.2 Restador............................................................................................................... 26
3.2.1.2.1 Clculo 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, representacin con signo y magnitud (bloque
n_adder_subs.vhd).......................................................................................................... 29
3.2.2 Multiplicador.. .......................................................................................................... 32
3.2.2.1 Multiplicador de 1x1 dgitos BCD (bloque one_digit_multiplier.vhd)................ 32
3.2.2.2 Multiplicador de Nx1 dgitos BCD (bloquen_by_one_multiplier.vhd)............... 34
3.2.2.3 Multiplicador de NxM dgitos BCD (bloquen_by_m_multiplier.vhd) ................ 37
3.2.3 Divisor .............................................................................................................................. 41
3.2.3.1 Algoritmo de divisin binaria ................................................................................. 41
3.2.3.2 Algoritmo de divisin BCD ..................................................................................... 42
3.2.3.3 Error generado........................................................................................................ 42
3.2.3.4 Divisor BCD (bloque divider.vhd)...................................................................... 43
3.3 Diseo de la Unidad Aritmtica Decimal ............................................................................... 48

- 19 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

3.1 La Unidad Aritmtica Decimal


Nuestro objetivo es la creacin del modelo VHDL de una Unidad Aritmtica Decimal, es
decir, una unidad que, operando en sistema BCD, realice las operaciones de suma, resta,
multiplicacin y divisin.

Figura 3.1. Representacin previa de la Unidad Aritmtica Decimal

Necesitaremos un sistema que dados dos valores de entrada de n dgitos BCD cada uno, x e
y, calcule el resultado z (de 2n dgitos BCD) de la operacin que hayamos escogido
previamente mediante la seal de entrada operation. Adems, contaremos con las seales
de entrada start (para iniciar el clculo interno cuando sea necesario), reset (reiniciar el
sistema), clk (seal 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 operacin.

Unidad aritmtica decimal

Sumador

Restador

Multiplicador

Divisor

Figura 3.2. Estructura interna previa de la Unidad Aritmtica Decimal

Por consiguiente, nos centraremos primero en el diseo de los mdulos primarios que
realizarn las diferentes operaciones y despus los integraremos en la unidad principal.

- 20 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2 Bloques de la unidad


3.2.1 Sumador/Restador
3.2.1.1 Sumador
En este apartado nuestro objetivo es la realizacin de un sumador de n dgitos decimales.
Para ello, lo primero que hacemos es crear una estructura bsica, el sumador de 1 dgito
decimal.

3.2.1.1.1 Sumador de 1 dgito 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 dgito decimal, tenemos una arquitectura cuya misin es realizar la suma de ambos
dgitos y dar como resultado (c) 1 dgito decimal de salida y un acarreo (carry_out) en caso
de ser necesario.

Figura 3.3. Sumador de 1 dgito decimal

La estructura interna del bloque sera la siguiente:

Figura 3.4. Arquitectura del sumador de 1 dgito decimal

- 21 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Tenemos dos entradas, a y b, que pueden representar cualquier dgito decimal del 0 al 9,
una salida c que tambin ser un dgito BCD, y un acarreo de salida (carry_out). Tambin
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 correccin 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
mximo nmero en decimal que podemos obtener es que el que se da cuando a y b tienen
sus valores mximos (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 sera 10011 (los cinco bits mencionados).
Para el caso de que la suma de a y b sea mayor que 9, aplicaremos un factor de correccin
que sera restar 10 al valor obtenido y aumentar 1 el dgito 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 correccin.
Empezamos sumando 5 y 7. Sus correspondientes en binario son 0101 para el 5 y 0111
para el nmero 7. El resultado es 12, que en binario se representa como 1100.
1

decimal

0 1 0 1
+ 0 1 1 1
1 1 0 0

5
7
12

Vemos que este valor es superior a 9, y por tanto no es un valor BCD vlido. Entonces
hemos de aplicar una correccin para obtener el valor correspondiente en BCD, donde el
nmero 12 se representara con dos dgitos 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 0 0
+
0 1 1 0
1 0 0 1 0

Equivale a un dgito BCD


de valor 1 (0001)

12
6

Equivale a un dgito BCD de


valor 2 (0010)

Obtenemos 10010, donde debemos leer los ltimos cuatro bits para el primer dgito
decimal 0010 y que equivalen al nmero 2, y el bit de ms peso, 1, que formara parte
del siguiente dgito decimal, que sera un 1. Por tanto, tendramos como resultado dos
dgitos decimales, un dgito decimal de las decenas igual a 1, y otro para las unidades que
sera un 2. Hemos pasado del valor 12, 10010 en binario, a su equivalente en
nomenclatura BCD, 0001 0010.
- 22 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Decimal
Binario
BCD

Memoria descriptiva

12
1100
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 continuacin podemos ver una simulacin del funcionamiento de este bloque:

Figura 3.5. Simulacin del sumador de 1 dgito decimal

Podemos observar como se realiza la correccin cuando a + b > 9, obteniendo como


resultado en c el dgito de las unidades, y el dgito 1 (0001) de las decenas en el acarreo
de salida (cy_out).

- 23 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2.1.1.2 Sumador de n dgitos decimales


Para obtener el sumador de n dgitos BCD vamos a interconectar n sumadores de 1 dgito
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 dgitos decimales

La interconexin de los bloques sencillos crear el sumador de n dgitos BCD,

Figura 3.7. Sumador de n dgitos decimales

donde tendremos dos entradas, x e y, de n dgitos BCD (4n bits), y una salida z que ser el
resultado de la operacin. Adems, 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 dgito BCD.

- 24 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

A continuacin se muestra la simulacin de unos ejemplos para n = 4:

Figura 3.8. Simulacin del sumador de 4 dgitos decimales

Podemos ver como en la tercera operacin (x = 3050, y = 8070), el acarreo de salida est a
nivel alto, lo que indica que el resultado es z = 11120.

- 25 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2.1.2 Restador
El objetivo es crear un bloque que dados dos valores de entrada de n dgitos, x e y, calcule
la diferencia z, e indique mediante una seal 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 dgitos decimales

Para ello, nos basaremos en dos operaciones bsicas; una es la suma descrita en el apartado
anterior, por lo que utilizaremos el Sumador de n dgitos decimales, y la otra es la
utilizacin del complemento a 10n del valor y de entrada. El complemento a 10n de un
nmero se puede obtener a partir de calcular el complemento a 9 de cada dgito (con un
bloque que haga esta funcin) 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 dgito y sumar 1 (lo que ya habamos avanzado anteriormente).
Se puede calcular la resta mediante la expresin 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)

- 26 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

3.2.1.2.1 Clculo del complemento a 9 (bloque nine_complement.vhd)


Diseamos un bloque que dado un dgito BCD de entrada (e), calcule su complemento a 9
(s). Este bloque estar controlado por una seal de entrada denominada add_sub,
encargada de habilitar o no la operacin. 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 dgito BCD

Dado un dgito BCD e de cuatro bits (e3 e2 e1 e0), su complemento a 9 (s3 s2 s1 s0) se
obtiene mediante la operacin 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:

s0 = e0
s1 = e1

(3.8)

s2 = e1 e2
s3 = e1 e2 e3

Si aadimos la seal de control add_sub, dichas expresiones quedan modificadas de esta


forma:

s0 = add _ sub e0 + add _ sub e0


s1 = e1
s 2 = add _ sub e2 + add _ sub (e1 e2 )

s3 = add _ sub e3 + add _ sub e1 e2 e3

(3.9)

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

- 27 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2.1.2.2 Sumador/Restador en complemento a 10n


Para implementar el restador utilizaremos, como hemos explicado antes, el sumador de n
dgitos y el bloque de complemento a 9 (nine_complement.vhd). El diagrama de bloques
resultante sera el mostrado a continuacin:

Figura 3.12. Restador de n dgitos decimales

Si nos fijamos en la Figura 3.12, podemos ver que la seal de control add_sub nos permite
realizar las operaciones de suma y resta:

Si add_sub = 0, la seal y no se modifica y tenemos la operacin suma (z = x + y)

Si add_sub = 1, lo que entra al sumador es el complemento a 9 de y; adems la


seal de entrada del sumador ini_carry (acarreo de entrada) toma el valor de
add_sub, por lo que la operacin 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 dgitos.

- 28 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

3.2.1.3 Sumador/Restador,
n_adder_subs.vhd)

representacin

con

signo

magnitud

(bloque

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 seal 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 operacin debemos calcular el
complemento a 10n del valor z que hemos obtenido; es decir, calcular el complemento a 9
de cada dgito de z y sumar 1 al resultado obtenido. Esto lo hacemos mediante una
modificacin de la arquitectura anterior, por lo que el diagrama de bloques final del
Sumador/Restador de n dgitos BCD ser el siguiente:
z1

y(4n-1:0)
add_sub

4n

x(4n-1:0)
4n

oc
carry_out

Complemento
a9
4n

4n

Complemento
a9

1
4n

Sumador de n

4n

Sumador de n

ini_carry

ini_carry
ini_carry

dgitos decimales

dgitos decimales

4n

4n

z1

z3

add_sub
4n

z(4n-1:0)
Figura 3.13. Sumador/Restador de n dgitos decimales

- 29 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Esta modificacin implica un cambio en el significado del valor del acarreo de salida del
bloque (denominado carry_out), cuando realizamos la operacin 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 aadido otro bloque que complementa a 9 el resultado z1 de la primera etapa y


posteriormente suma 1, lo que genera la seal 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 dgitos decimales presenta las siguientes
caractersticas:
add_sub

Operacin

carry_out

Resultado

Suma

Exacto

Suma

Hay desbordamiento

Resta

Positivo

Resta

Negativo

Tabla 3.1. Operaciones del Sumador/Restador

A continuacin mostramos unos ejemplos de la simulacin para n = 4:


En modo resta (add_sub = 1):

Figura 3.14. Simulacin del Sumador/Restador en modo resta

- 30 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

En modo suma (add_sub = 0):

Figura 3.15. Simulacin del Sumador/Restador en modo suma

- 31 -

Memoria descriptiva

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

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

Figura 3.16. Multiplicador de NxM dgitos BCD

Para ello lo primero que haremos ser definir una estructura bsica que realizar la
multiplicacin de dos dgitos BCD (multiplicador de 1x1 dgitos BCD), despus
realizaremos un bloque que multiplique un nmero de n por 1 dgitos BCD, y finalmente el
multiplicador de NxM dgitos BCD.

3.2.2.1 Multiplicador de 1x1 dgitos BCD (bloque one_digit_multiplier.vhd)


El producto decimal se puede obtener a travs del producto binario y una etapa de
correccin posterior. La etapa bsica sera un multiplicador de 1x1 dgitos BCD, es decir,
dos entradas de 1 dgito BCD cada una. sta se puede implementar a partir de un circuito
combinacional.
b(3:0)

a(3:0)

Multiplicador de
1 dgito BCD

d(3:0)

u(3:0)

Figura 3.17. Multiplicador de 1x1 dgitos BCD

- 32 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

Tenemos A y B que son dos dgitos BCD (a3 a2 a1 a0 y b3 b2 b1 b0 respectivamente). El


producto BCD de ambos dgitos se puede expresar como:
A B = D 10 + U ,

(3.10)

es decir, la cifra de las decenas multiplicada por 10 ms las unidades.


El producto binario de A y B se puede expresar en un primer paso como un nmero de 7
bits tal que:

A B = P = p6 p5 p4 p3 p2 p1 p0

(3.11)

Son un mximo de 7 bits porque el resultado mximo que podemos tener en esta operacin
es 81 en decimal, que corresponder al caso de que A y B tengan su valor mximo, y este
es 9. La representacin binaria del nmero 81 es 1010001 (7 bits).
Podemos convertir el nmero binario P a cdigo BCD mediante sumas binarias tras
corregir los trminos descritos en la Figura 3.18. La primera fila indica el peso de cada
dgito 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).
80

+
d3

40

20

10

8
4 2 1
p3 p2 p1 p0
p4
p4 p4
p5 p5
p5
p6 p6
p6
d2 d1 d0 u3 u2 u1 u0

Figura 3.18. Reduccin aritmtica de binario a BCD

Sumamos los trminos y obtenemos las expresiones que nos darn el valor de las unidades
(uu) y las decenas (dd):

uu = p3 p2 p1 p0 + 0 p4 p4 0 + 0 p6 p5 0
dd = p6 p5 p4 + 0 p6 p5

(3.12)

Dada esta ltima expresin de uu, podemos ver que su valor estar entre 0 y 27 (segn los
valores de p0, p1, p2, p3, p4, p5 y p6). Si el valor de uu es superior a 9 (con lo que se
necesitara de ms de 1 dgito BCD para representarse) deberemos realizar una correccin
para obtener un resultado correcto. A continuacin definimos dichos trminos de
correccin:

Si uu 9: no hacemos ninguna correccin, el valor es correcto,


Si 9 < uu 19: sumamos 1 a dd, (aadimos 1 a las decenas y 6 a las unidades; esto
ltimo equivale a restar 10),
Si 19 < uu: sumamos 2 a dd, (aadimos 2 a las decenas y 12 a las unidades; esto
ltimo equivale a restar 20).
- 33 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

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:

gt 9 = uu 4 uu 3 (uu 2 uu1 )

Si uu es mayor o igual a 20:

gt 20 = uu 4 (uu 3 uu 2 )

(3.13)

(3.14)

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

gt10st19 = gt 9 gt 20

(3.15)

Por ltimo obtenemos los valores finales para las decenas (d) y las unidades (u) al aadir
las correcciones pertinentes:
u = (uu3 uu2 uu1 uu0) + (gt20 gt9 gt10st19 0)
d = (dd3 dd2 dd1 dd0) + (0 0 gt20 gt10st19)

(3.16)

Simulacin

Figura 3.19. Muestra de la simulacin del multiplicador de 1x1 dgitos BCD

3.2.2.2 Multiplicador de Nx1 dgitos BCD (bloque n_by_one_multiplier.vhd)

Un multiplicador de Nx1 dgitos BCD se puede construir a partir de n multiplicadores de


1x1 dgitos 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 dgitos BCD, one_digit_multiplier.vhd) y el otro ser el
sumador de 1 dgito BCD (one_digit_adder.vhd).

- 34 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

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


x2

y
4

x1

x0

Multipl.
1x1 BCD

y
4

Multipl.
1x1 BCD

d2

Multipl.
1x1 BCD

u2

d1

u1

d0

u0

Figura 3.20. Multiplicador de 3x1 dgitos BCD (parte 1)

donde x ser el nmero de 3 dgitos 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 dgitos BCD.
El resultado z (formada por 4 dgitos BCD) ser el siguiente:
z = (0 u2 u1 u0) + (d2 d1 d0 0)
0

d2

u2

Sumador 1
dgito BCD
4

d1

u1

Sumador 1
dgito BCD

z3

d0

Sumador 1
dgito BCD

(3.17)
u0
4

Sumador 1
dgito BCD

z2

z1

z0

Figura 3.21. Multiplicador de 3x1 dgitos BCD (parte 2)

Viendo este ejemplo podemos afirmar que, para un multiplicador de Nx1 dgitos BCD,
necesitaremos n multiplicadores 1x1 y n + 1 sumadores de 1 dgito.

- 35 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

Tendremos dos seales de entrada: un valor x de n dgitos (xn-1 xn-2 x2 x1 x0) y un valor y
de 1 dgito, lo que generar una seal de salida z (zn zn-1 zn-2 z2 z1 z0).

Figura 3.22. Multiplicador de Nx1 dgitos. Incluye n multiplicadores 1x1 y n + 1 sumadores de 1 dgito

A continuacin se muestra un ejemplo de la simulacin del bloque para n = 5:

Figura 3.23. Simulacin del multiplicador Nx1 dgitos BCD

- 36 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2.2.3 Multiplicador de NxM dgitos BCD (bloque n_by_m_multiplier.vhd)

En este bloque tenemos como datos iniciales dos nmeros decimales, x e y, de n y m


dgitos respectivamente (xn-1 xn-2 x2 x1 x0 e ym-1 ym-2 y2 y1 y0). El resultado ser z, un
nmero decimal de n + m dgitos (z(n+m)-1 z(n+m)-2 z2 z1 z0).

Figura 3.24. Multiplicador de NxM dgitos BCD

Tambin tendremos las entradas start (indica inicio de operacin), clk (seal de reloj) y
reset (que inicializa el bloque), y la salida done (que informa de operacin realizada).
Los valores n y m sern los parmetros genricos del circuito.
Para realizar esta operacin vamos a crear un sistema secuencial (a diferencia de los que
habamos hecho hasta ahora, que eran combinacionales) en el que mediante un bucle,
utilizaremos m veces el multiplicador de Nx1 dgitos (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;

- 37 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

El diagrama de bloques del circuito es:


1111

y(4m-1:0)
4m

x(4n-1:0)
int_y(m)
4n

left shift register y

load
shift
clk

Multiplicador Nx1
dgitos BCD
z_by_10
4(n+1)

x_by_yi
4(n+m)

Sumador n
dgitos BCD
x 10
next_z
load
shift
clk

register z

z(4(n+m)-1:0)
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 dgito 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 posicin (4 bits) a la izquierda. De esta manera entrarn sucesivamente en el
multiplicador Nx1 los dgitos ym-1, ym-2, y1, y0; una seal interna detectar el 1111 e
indicar el fin de clculo.
En el multiplicador Nx1 tendremos en una entrada el valor de x, multiplicando cada vez
por el dgito de y correspondiente. Es decir, en un primer paso el multiplicador realizara el
producto de xn-1 xn-2 x1 x0 e ym-1. El valor resultante pasara al sumador, donde no se
modificara ya que el registro z se inicializa con 0, y se almacenara en dicho registro.
En la siguiente etapa, se desplazar el registro de desplazamiento otra posicin; 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 dgito no decimal 1111 en el registro de
desplazamiento que indica que se han ledo todos los valores de y.

- 38 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

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

Figura 3.26. Simulacin del multiplicador NxM dgitos BCD

Para controlar este sistema secuencial necesitaremos una unidad de control. Dicha unidad
recibir como seales de entrada start, clk, reset y end_of_computation, y generar las
seales shift, load y done:

Figura 3.27. Unidad de control

La unidad de control se puede representar con una mquina de 4 estados:


end_of_ computation = 1
start = 0

start = 1

E0
shift = 0
load = 0
done = 1

start = 0

E1
shift = 0
load = 0
done = 1

end_of_ computation = 0

start = 1

E2

E3

shift = 0
load = 1
done = 0

shift = 1
load = 0
done = 0

Figura 3.28. Mquina de estados de la unidad de control

- 39 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

E0 es el estado inicial (seal current_state), con un bucle de espera para que la seal start
pase a nivel bajo y avanzar al estado 1 (caso de que start se haya mantenido a 1 como
consecuencia de una operacin anterior).
Aqu se espera a que start sea igual 1 (lo que hemos hecho ha sido detectar la transicin
de 0 a 1 de esta seal). En E2 se cargan los valores iniciales en los registros (load = 1).
Entonces pasamos a E3, donde se ejecutan las etapas de clculo (shift = 1) hasta que la
seal end_of_computation sea igual a 1, lo que significar que el dgito ledo int_y es 15
(1111) y ha finalizado la operacin, volviendo al estado inicial y poniendo la seal done a
1, indicando que el proceso ha terminado.

- 40 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2.3 Divisor
3.2.3.1 Algoritmo de divisin binaria

Dados dos nmeros naturales x e y, siendo x < y, el algoritmo de divisin binaria genera
dos naturales q y r tales que:
x 2 p = q y + r , con r < y

(3.18)

x = q y 2 p + r 2 p ,

(3.19)

r
x
r
= q 2 p + 2 p , siendo 2 p < 2 p
y
y
y

(3.20)

As

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 ecuacin 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 expresin 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 funcin de ri-1 e y:


2 ri-1 = qp-i y + ri, siendo ri < y

(3.24)

qp-i = 1 y ri = 2 ri-1 y

(3.25)

qp-i = 0 y ri = 2 ri-1

(3.26)

Se plantean dos opciones:

2 ri-1 y : entonces

2 ri-1 < y : entonces

- 41 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2.3.2 Algoritmo de divisin BCD

El algoritmo de divisin binaria se puede utilizar cualquiera que sea el sistema de


numeracin. Si trabajamos en base 10, la nica condicin 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 sern la multiplicacin por 2, la resta con
generacin de signo y la suma. Adems, la representacin 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 (segn el algoritmo). Supongamos que el
objetivo sea que el resultado se escriba con m dgitos 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 relacin:
p

1
1
< , es decir p > m log 2 (10) , o sea que p > 3.3 m
2
10

- 42 -

(3.27)

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.2.3.4 Divisor BCD (bloque divider.vhd)

El divisor BCD ser un mdulo que realice la divisin entre dos valores de entrada, x / y,
donde x < y (para que el algoritmo funcione), dando como resultado el cociente q de m
dgitos decimales (qm-1 qm-2 q2 q1 q0).
Tambin tendr como entradas las seales start (inicio de operacin), clk (seal de reloj) y
reset (que inicializa el bloque), y la salida done (que informa de operacin realizada).

Figura 3.29. Divisor BCD

El cociente q es una salida de m dgitos. Internamente, el cociente debe generarse con p


dgitos, donde p es del orden de 3.3m (segn hemos explicado anteriormente). Llmese qq
al cociente interno con p dgitos. El cociente q (el resultado que nosotros veremos) consta
de los m dgitos ms significativos de qq.
Los valores de n (dgitos de los valores de entrada), m (dgitos y por tanto precisin del
resultado, el cociente), p (nmero de iteraciones que se realizarn) y logp (nmero de bits
necesario para representar p) sern los parmetros genricos del modelo.

- 43 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Basndonos en el algoritmo de ejecucin creamos el siguiente diagrama de bloques:


r

0010

4n

Multiplicador
Nx1 dgitos BCD
4n+4

qq

y(4n-1:0)
rr

ulp

4p

4n

4p

ulp

0101

4p
carry_out

add_sub

carry_out

Sumador/Restador
n dgitos BCD

add_sub

Sumador/Restador
n dgitos BCD

Multiplicador
Nx1 dgitos BCD

rr_y(4n-5:0)

4p+4
4p

load
clk

initially: 0.5
4p

4n

4p

ulp
load
clk

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

initially: 0
4p

4n

4p

qq

4p-4(p-m)

q(4m-1:0)
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 dgitos BCD
(n_by_one_multiplier.vhd). En una entrada tendremos el valor r y en la otra el dgito 2
(0010 en binario).
La diferencia entre el doble de r (2r, seal rr) y el valor decimal de entrada y, la
calculamos mediante un Sumador/Restador de n dgitos BCD (n_adder_subs.vhd) en
modo resta (seal de entrada add_sub = 1).
Si el resultado de la resta es positivo (rr > y) entonces carry_out = 0 y se almacenarn en
el registro r los n dgitos menos significativos de la diferencia recin calculada (rr - y). Si
por el contrario rr < y, carry_out = 1, se almacenarn en el registro los n dgitos menos
significativos del valor de rr.
- 44 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

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 dgitos 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 seal ulp (Unit in the Least significant Position, unidad en la posicin menos
significativa) es un nmero que al final del clculo tendr p dgitos. Su registro
(register_ulp) se inicializa con el valor 0.5 (0000 0101 en cdigo BCD). En cada
iteracin 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 dgitos,
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
nmero de p + 1 dgitos, slo utilizaremos los p dgitos de ms peso (lo que equivale a
dividir por 10).
Al acabar el clculo de la operacin (seal zero = 1), obtendremos el cociente q de
truncar el ltimo valor almacenado en el registro qq, a partir del nmero de dgitos m que
hayamos seleccionado.
Unidad de control
Este sistema que hemos creado tambin 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 seales load (escritura de los valores iniciales en los
registros), ce (actualizacin de los registros) y done (operacin finalizada).
La seal zero vendr controlada por un contador de p estados (este nmero se representa
con logp bits, como hemos dicho antes). Dicha seal se pondr a 1 cuando se ejecute el
paso p de la iteracin.

- 45 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

La mquina de estados asociada a la unidad de control es la siguiente:

Figura 3.32. Mquina de estados de la unidad de control del divisor

Simulacin
A continuacin mostramos un ejemplo de la simulacin del sistema para los valores
genricos n = 3, m = 8, p = 27 y logp = 5:

Figura 3.33. Simulacin del divisor

La divisin entre x = 335 e y = 927 genera el cociente q = 36138079, que representa


0.36138079 (como x < y, el primer dgito siempre es 0). Al haber definido m = 8, el
cociente est representado por 8 dgitos decimales.

- 46 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

Podemos observar con mayor facilidad en la Figura 3.34 la transicin entre estados, y
vemos como, desde el estado 0 (seal current_state) y dado que la seal start es 0,
pasamos al estado 1 (en caso de que start se hubiera mantenido a 1 como resultado de un
clculo anterior, el sistema esperara a que dicha seal se pusiera a 0).

Figura 3.34. Ampliacin de la Figura 3.33

En el estado 1 y tras detectar un flanco de subida de la seal start, pasamos al estado 2,


donde la unidad de control activa (a 1) la seal load y se escriben los valores iniciales en
los registros. La seal done se pone a 0 indicando que hay una operacin en curso.
Tras un ciclo de reloj pasamos al estado 3 y se inicia el clculo; aqu empieza a funcionar
el contador regresivo (count) de p estados (27 en el ejemplo, de 26 a 0) que determina el
nmero de iteraciones a realizar. Tambin se activa la seal ce que permitir actualizar los
registros. Cuando el contador llegue a 0, dejarn de actualizarse los registros (ce = 0) y se
activar la seal zero informando del fin de clculo (esto se puede ver en la Figura 3.33),
volviendo al estado 0 y ponindose el indicador de operacin realizada done a nivel alto.

- 47 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

3.3 Diseo de la Unidad Aritmtica Decimal (bloque arithmetic_unit.vhd)

El siguiente paso es la definicin de la Unidad Aritmtica Decimal, una estructura que


integre los tres bloques anteriores (Sumador/Restador de n dgitos decimales,
Multiplicador de NxM dgitos BCD y Divisor BCD).

Figura 3.35. Unidad Aritmtica Decimal

Los parmetros genricos del modelo sern:

n: tamao de los operandos (en dgitos decimales) de x e y


p: nmero de etapas de la divisin
logp: nmero de bits necesario para representar p

Este bloque estar controlado por una seal de entrada llamada operation, mediante la cual
se indicar a la unidad la operacin a realizar:
operation Operacin

Resultado

00

Suma

z=x+y

01

Resta

z=x-y

10

Multiplicacin

z=xy

11

Divisin

z = x / y (con una precisin de 2n dgitos fraccionarios)

Tabla 3.2. Operaciones de la Unidad Aritmtica Decimal

Tanto para la suma como la resta z tendr un tamao de 4n + 1 bits (el bit de mayor peso
corresponde a la seal carry_out del bloque Sumador/Restador), mientras que para la
multiplicacin y divisin el tamao ser de 8n bits.
En la multiplicacin y la divisin el clculo empieza con un flanco de subida de la seal de
entrada start. La bandera done se pone a 0. Una vez disponible el resultado, done tomar
el valor 1.

- 48 -

Memoria descriptiva

Diseo sobre FPGA de una Unidad Aritmtica Decimal

El diagrama de bloques de la unidad se muestra a continuacin:


x(4n-1:0)
y(4n-1:0)
operation1
operation0
start
4n

4n

carry_out

c_out

4n

4n

4n

4n

add_sub

Sumador/Restador
n dgitos BCD

Multiplicador de
NxM dgitos BCD

start1
clk
reset

4n

8n

8n

done1

s2

s1

Divisor de n
dgitos BCD

start2
clk
reset

s3

done2

operation

00

01

10

11

00

01

10

11

00

01

10

MUX-1

MUX-2

MUX-3

4n

4n

4n

z(4n-1:0)

z(8n-1:4n)

11

done

Figura 3.36. Diagrama de bloques de la Unidad Aritmtica Decimal

De cara a la implementacin en la FPGA, el operando y del Multiplicador de NxM dgitos


decimales pasar de estar formado por m dgitos a estarlo por n (podemos decir que ahora
el bloque es un Multiplicador de n dgitos decimales) De esta manera unificamos los
valores de entrada, que siempre estarn formados por n dgitos decimales.
Utilizaremos el bit de menor peso de la seal operation para indicar al Sumador/Restador
la operacin a realizar (entrada add_sub de ste).
Para habilitar el bloque multiplicador utilizaremos la seal 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 tambin de tres
entradas, pero esta vez sin negar el bit de menos peso de operation.

Figura 3.37. Circuito generador de las seales start1 y start2

- 49 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

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 multiplicacin (operation = 10) o divisin (operation = 11), que sera
z(4n-1:0).
El segundo multiplexor recibe a travs de sus dos primeros canales el valor de la seal
carry_out del Sumador/Restador (llamada c_out). Como este valor ocupa 1 solo bit, los
otros bits del dgito de menos peso sern 0 (el dgito de menor peso, 4n+3:4n, estar
formado por 0 0 0 c_out); los dems dgitos (8n-1:4n+4) sern 0. Para la multiplicacin y
la divisin mostrar la parte alta del resultado, los dgitos de mayor peso (8n-1:4n).
MUX-3 muestra el valor actual de la seal done, que estar a nivel alto excepto cuando se
realice el clculo de la multiplicacin o de la divisin (periodo en que la seal se pondr a
nivel bajo, debido a que done1 o done2 tomarn este valor).
A continuacin se muestra una simulacin del sistema con los parmetros n = 8 y p = 56
(en consecuencia logp = 6), para las diferentes operaciones:

Figura 3.38. Simulacin de la Unidad Aritmtica 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 dgitos BCD, ya que habamos 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 dgito 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 simulacin de la unidad cuando queremos realizar la
multiplicacin de dos valores (seleccionando operation = 10):

- 50 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria descriptiva

Figura 3.39. Simulacin de la Unidad Aritmtica Decimal (multiplicacin)

Al iniciarse el clculo, la seal que lo indica (done1) se pone a 0, lo que provoca que la
salida del sistema done tambin lo haga. Al acabar la ejecucin, done1 vuelve a nivel alto y
done tambin. Vemos como start1 se activa habilitando el multiplicador, en cambio start2
sigue a nivel bajo.
Por ltimo tenemos la simulacin de la unidad cuando ejecutamos la operacin de divisin
(operation = 11).

Figura 3.40. Simulacin de la Unidad Aritmtica Decimal (divisin)

Observamos la influencia de la seal done2 en done (tomando el valor 0 durante la


ejecucin, las p etapas que habamos explicado anteriormente). El resultado z se debe leer
como 0.3689331910348556.

- 51 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

4. MEMORIA EXPERIMENTAL

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

4.1 Descripcin del proceso ........................................................................................................... 54


4.2 Especificaciones ........................................................................................................................ 54
4.3 Elementos necesarios................................................................................................................ 55
4.4 Arquitectura a desarrollar ...................................................................................................... 55
4.5 Mdulos IP de terceros utilizados........................................................................................... 57
4.5.1 Microcontrolador PicoBlaze (mdulo kcpsm.vhd)........................................................ 57
4.5.2 Interfaz LCD (mdulo lcd_interface.vhd)..................................................................... 58
4.6 Memoria de programa (mdulo program_memory.vhd) ................................................... 60
4.7 Generacin del circuito (mdulo main.vhd) ....................................................................... 62
4.8 Asignacin de pines en la FPGA (archivo pins.ucf) .......................................................... 63
4.9 Implementacin en la FPGA ................................................................................................... 65
4.9.1 Generacin del archivo ..................................................................................................... 66
4.9.2 Implementacin en la FPGA ............................................................................................ 68

- 53 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

4.1 Descripcin del proceso

En este captulo describiremos la implementacin del componente virtual que hemos


creado, la Unidad Aritmtica 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 ejecutarn, una interfaz que
visualice los datos en la pantalla de la placa, y nuestra unidad, como principales elementos.
Como CPU utilizaremos un mdulo IP proporcionado por Xilinx, el microcontrolador de 8
bits PicoBlaze (kcpsm.vhd); para la interfaz de visualizacin de datos, el mdulo
lcd_interface.vhd, que es un mdulo previamente generado en proyectos anteriores
El primer paso consistir en la creacin de la memoria de programa que utilizar
PicoBlaze, utilizando la aplicacin pBlaze IDE. Despus crearemos un modelo VHDL que
incluya los mdulos mencionados antes. Por ltimo, implementaremos todo el diseo en la
FPGA mediante el paquete Xilinx ISE Desing Suite.

4.2 Especificaciones

Consideremos las dos lneas de 16 caracteres cada una que posee la placa, y que se
distribuyen de la siguiente manera: en la primera lnea, los 8 primeros dgitos (BCD)
corresponden al operando x, y los 8 ltimos al operando y. La segunda lnea ser el
resultado z.

Figura 4.1. Posicionamiento de los dgitos en el display

Un primer pulso (pulso 0) de synch (seal de sincronizacin) borra el display. Mediante los
interruptores SW3, SW2, SW1 y SW0 (pesos 8, 4, 2, 1 respectivamente) el dgito de
entrada, y con el pulsador synch procedemos a almacenarlo en el registro interno
correspondiente y visualizarlo en pantalla.
Tras haber introducido los 16 dgitos (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 multiplicacin y la
divisin. Un ltimo pulso (pulso 21) dar la seal para limpiar el visualizador.

- 54 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

La siguiente figura ilustra el proceso que acabamos de describir:


pulso 0
pulso 1

pulso 2

02

pulso 3

028
...

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 3

0000000053167058
pulso 18 0 2 8 6 7 3 3 5 5 0 2 9 9 7 2 3

0000000147432388
...
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 dgito BCD de entrada
data_in.
Pulsadores para las seales synch (de sincronizacin) 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 dgitos, la codificacin (a ASCII) de los datos
y la ejecucin de las diferentes operaciones. Las operaciones se definirn mediante
un juego de instrucciones en lenguaje ensamblador, que posteriormente formarn la
memoria de programa.
Una interfaz para el display LCD.
La Unidad Aritmtica Decimal.

- 55 -

Memoria experimental

Diseo sobre FPGA de una Unidad Aritmtica Decimal

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


data_in

synch

mult_out
in_port

done
15

z (15:0)
PicoBlaze
(CPU and
program memory)

reset
clk

port_id
write_strobe

operation

out_port

Registro
temp_write

Registro
8*4 bits

x (7:0)
Registro
8*4 bits

Registro
i_write

d_write
ready

lcd_interface

lcd_data

y (7:0)

Registro
2 bits

clk

clk

Unidad Aritmtica
Decimal

start
reset
clk

lcd_e

lcd_rs

lcd_rw

Figura 4.3. Diagrama de bloques del sistema

Como CPU del sistema utilizaremos el microcontrolador PicoBlaze proporcionado por


Xilinx; emplearemos dos componentes virtuales ms, el modelo VHDL de una interfaz
LCD y nuestra Unidad Aritmtica Decimal, que es el mdulo que queremos testear.

- 56 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

4.5 Mdulos 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 (mdulo 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 mdulo no requiere soporte externo y proporciona un entorno flexible para conectarlo
a otros componentes. Se suministra como descripcin VHDL.
El ensamblador pBlaze IDE permite crear el modelo VHDL de la memoria de programa
que utilizar el microcontrolador.
Algunas caractersticas de PicoBlaze son:

Posee 16 registros de 8 bits de propsito general (s0 a sF).


256 puertos de entrada y 256 de salida.
Rpida respuesta a interrupciones (el peor caso es de 5 ciclos de reloj).
Soporta programas de hasta 256 instrucciones.
El tamao de las instrucciones es de 16 bits.
Todas las instrucciones se ejecutan en 2 ciclos de reloj.

Estructura
A continuacin podemos ver el diagrama de bloques del mdulo PicoBlaze.

Figura 4.4. Diagrama de bloques del mdulo PicoBlaze

- 57 -

Memoria experimental

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Arquitectura

Figura 4.5. Arquitectura interna de PicoBlaze

4.5.2 Interfaz LCD (mdulo lcd_interface.vhd)

Es un mdulo VHDL que aade la funcionalidad necesaria para presentar datos en el


visualizador de la FPGA.
temp_write

i_write

d_write

ready
reset
clk

lcd_interface

lcd_data

lcd_e

lcd_rs

lcd_rw

Figura 4.6. Mdulo lcd_interface

- 58 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

La entrada de 8 bits temp_write puede ser un carcter (cdigo ASCII) o un comando. La


entrada de control i_write enva el comando temp_write a la pantalla, y la entrada de
control d_write hace lo mismo pero con un carcter (Figura 4.7). La seal ready se activa
cuando la interfaz est disponible para una nueva operacin.

Figura 4.7. Operaciones

Este componente implementa internamente 4 retardos diferentes mediante un contador


programable, para una correcta visualizacin 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.)

01
80
C0

Operacin

Limpiar el display
Fijar el cursor al inicio de la primera lnea
Fijar el cursor al inicio de la segunda lnea
Tabla 4.1. Comando utilizados

- 59 -

Memoria experimental

Diseo sobre FPGA de una Unidad Aritmtica Decimal

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


d_write

temp_write

very_short
very_long
short long
ce_cd

ce

sel_delay

cd(7..0)

status
(to control unit)

counter

cd(7..4)

load

load

cd(3..0)
1

time_out
(to control unit)

sel_nibble

i_write

nibble
(to control unit)

status
time_out
nibble

s_write ready

control unit

reset
clk

lcd_data

ce_cd
sel_nibble
sel_delay
load

lcd_e lcd_rs lcd_write


(= 0)

Figura 4.8. Circuito de la interfaz LCD

4.6 Memoria de programa (mdulo 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 emplearn y las instrucciones que se ejecutarn
(incluyendo un programa principal y diversas subrutinas). Este paso lo llevaremos a cabo
mediante la aplicacin pBlaze IDE, que nos permitir ensamblar y simular nuestro cdigo,
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 segn la siguiente tabla:
seal

direccin

z
synch
data_in
ready
done

00 a 0f
10
11
12
13

Tabla 4.2. Direcciones de entrada

- 60 -

Memoria experimental

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Y las de salida:
seal

direccin

y
x
temp_wr
id_write
start
operation

00 a 07
08 a 0f
10
11
12
13

Tabla 4.3. Direcciones de salida

El algoritmo utilizado sera 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 tamao del cdigo, se incluira una subrutina (entre otras) que
mostrara el resultado z en el visualizador despus de cada operacin:
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;

- 61 -

Memoria experimental

Diseo sobre FPGA de una Unidad Aritmtica Decimal

4.7 Generacin del circuito (mdulo 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 Aritmtica Decimal (arithmetic_unit.vhd), ya podemos disear nuestro circuito
completo. Aadiremos varios registros necesarios para el funcionamiento del sistema.
El diagrama de bloques es el que hemos mostrado antes:
data_in

synch

mult_out
done

in_port

15

z (15:0)
PicoBlaze
(CPU and
program memory)

reset
clk

port_id
write_strobe

operation

out_port

Registro
temp_write

Registro
8*4 bits

x (7:0)
Registro
8*4 bits

Registro
i_write

d_write
ready

lcd_interface

lcd_data

y (7:0)

Registro
2 bits

clk

clk

Unidad Aritmtica
Decimal

start
reset
clk

lcd_e

lcd_rs

lcd_rw

Figura 4.9. Diagrama de bloques del sistema

Definiremos la Unidad Aritmtica Decimal con los siguientes parmetros:

n = 8, lo que quiere decir que los operandos x e y sern de 8 dgitos BCD cada uno,
p = 56, es el nmero de etapas que se ejecutarn para calcular el resultado cuando
realicemos la divisin,
logp = 6, que son los bits necesarios para representar el valor de p.

- 62 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

Utilizaremos 2 registros de 32 bits (8 dgitos 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 seal operation
tendremos suficiente con un registro de 2 bits.
Otros 2 registros ms sern necesarios para las seales temp_write y i_write/d_write de la
interfaz LCD.
Tambin incluiremos un divisor de frecuencia ya que la proporcionada por el reloj de la
placa es demasiado alta (50 MHz). En el circuito se aaden cuatro divisores de frecuencia
que generan clk_2, clk_4, clk_8 y clk; esta ltima seal es la que se utilizar como seal 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 Asignacin de pines en la FPGA (archivo pins.ucf)

El siguiente paso consiste en crear un archivo UCF (User Constraint File) que asigne las
seales 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) sern asignados a
los siguientes pines (entre parntesis):

data_in<3> SW3 (N17)


data_in<2> SW2 (H18)
data_in<1> SW1 (L14)
data_in<0> SW0 (L13)

Figura 4.10. Distribucin de los interruptores SW

- 63 -

Memoria experimental

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Pulsadores:

synch BTN_WEST (D18)


reset BTN_SOUTH (K17)

Figura 4.11. Pulsadores disponibles en la placa

Seal de reloj:

ext_clk CLK_50MHz (C9)

Figura 4.12. Seales de reloj disponibles

Seales de la interfaz LCD:


Seal

Nombre interno

PIN asociado

lcd_e
lcd_rs
lcd_rw
lcd_data<3>
lcd_data<2>
lcd_data<1>
lcd_data<0>

LCD_E
LCD_RS
LCD_RW
SF_D<11>
SF_D<10>
SF_D<9>
SF_D<8>

M18
L18
L17
M15
P17
R16
R15

Tabla 4.4. Asignacin de pines para la interfaz LCD

- 64 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

Figura 4.13. Interfaz LCD

4.9 Implementacin 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 asignacin de pines (pins.ucf),
procederemos a sintetizarlo e implementarlo en la FPGA.
Para ello utilizaremos la aplicacin 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 Aritmtica 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

- 65 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

4.9.1 Generacin 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 caractersticas del
dispositivo que estamos utilizando, que en nuestro caso sern las siguientes:

Figura 4.14. Caractersticas de la FPGA

Aadimos los modelos VHDL y el archivo pins.ucf:

Figura 4.15. Archivos utilizados en el proyecto

- 66 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

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

Figura 4.16. Jerarqua 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. Utilizacin del dispositivo

Ahora realizamos la implementacin (Implement Design), el Placement & Routing, que


nos da una descripcin concreta de los recursos necesarios de la FPGA para grabar nuestro
diseo:

Tabla 4.6. Utilizacin del dispositivo

- 67 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

El siguiente paso consiste en generar el archivo de programacin (Generate Programming


File). Ya tenemos creado nuestro archivo main.bit que ser el que bajemos a la placa.

4.9.2 Implementacin en la FPGA

Grabaremos nuestro diseo (archivo main.bit) a travs del puerto USB de la Spartan-3E.
Desde Configure Target Device, seleccionamos Manage Configuration Project (iMPACT),
los que nos llevar a la aplicacin iMPACT. A travs 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


diseo. 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
estn (Bypass). Ejecutamos Program en xc3s500e y ya tenemos la unidad operativa (el led
DONE de la placa se enciende indicando que el proceso de implementacin se ha
completado correctamente).

Figura 4.18. FPGA disponible para su utilizacin

- 68 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Memoria experimental

A continuacin 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 dgito z8 (segn la Figura


4.1) es 1.

Figura 4.20. Resultado de la resta

Multiplicacin: el resultado es 144226156248205.

Figura 4.21. Resultado de la multiplicacin

Divisin: el resultado se ha de interpretar como 0.0570049858922682.

Figura 4.22. Resultado de la divisin

- 69 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

5. ANEXOS

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Anexos

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


5.1.1 Sumador de 1 dgito BCD (one_digit_adder.vhd)............................................................ 72
5.1.2 Complemento a 9 (nine_complement.vhd) ....................................................................... 73
5.1.3 Sumador/Restador de n dgitos decimales (n_adder_subs.vhd) ....................................... 73
5.1.4 Multiplicador de 1x1 dgitos BCD (one_digit_multiplier.vhd) ........................................ 75
5.1.5 Multiplicador de Nx1 dgitos BCD (n_by_one_multiplier.vhd) ....................................... 76
5.1.6 Multiplicador de NxM dgitos BCD (n_by_m_multiplier.vhd) ........................................ 78
5.1.7 Divisor BCD (divider.vhd) ............................................................................................... 80
5.1.8 Unidad Aritmtica 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 Asignacin de pines en la Spartan-3E (pins.ucf) .................................................................... 97

- 71 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal

5.1 Modelos VHDL

A continuacin se detallan los diferentes modelos VHDL creados en los apartados


anteriores.

5.1.1 Sumador de 1 dgito BCD (one_digit_adder.vhd)


-----------------------------------------------------------------------Entidad del sumador de 1 dgito 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 dgito 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
--Declaracin de seales
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)));
correction <= '0' & cy_out & cy_out & '0';
c <= d(3 DOWNTO 0) + correction;

END architecture_oda;

- 72 -

--crea carry de salida


--si d>9
--se pone a '0110' si hay
--carry de salida
--aplica la correccin si
--hay carry de salida

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Anexos

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);
--dgito de entrada
add_sub: IN STD_LOGIC;
--seal de control del bloque
s:
OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
--dgito 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)
s(1)
s(2)
s(3)

<=
<=
<=
<=

(NOT(add_sub)
e(1);
(NOT(add_sub)
(NOT(add_sub)
NOT(e(2)) AND

AND e(0)) OR (add_sub AND NOT(e(0)));


AND e(2)) OR (add_sub AND (e(1) XOR e(2)));
AND e(3)) OR (add_sub AND (NOT(e(1)) AND
NOT(e(3))));

END architecture_nc;

5.1.3 Sumador/Restador de n dgitos decimales (n_adder_subs.vhd)


-----------------------------------------------------------------------Entidad del sumador/restador de n dgitos 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 dgitos BCD
y:
IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dgitos BCD
add_sub: IN STD_LOGIC;
--operacin: '0' suma y '1' resta
z:
OUT STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --salida de n dgitos BCD
carry_out: OUT STD_LOGIC);
--acarreo de salida
END n_adder_subs;

- 73 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal

-----------------------------------------------------------------------Arquitectura del sumador/restador de n dgitos 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
--Declaracin de constantes
CONSTANT i1: STD_LOGIC_VECTOR(4*n-1 DOWNTO 0) :=
CONV_STD_LOGIC_VECTOR(1,4*n);
--Declaracin de seales
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;
--Declaracin 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);
--dgito de entrada
add_sub: IN STD_LOGIC;
--seal de control del bloque
s:
OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
--dgito de salida
END COMPONENT;
--Inicio
BEGIN
carries(0) <= add_sub;
a1_iteration: FOR i IN 0 TO n-1 GENERATE
nine_compl: nine_complement PORT MAP(
e => y(4*i+3 DOWNTO 4*i),
add_sub => add_sub,
s => y1(4*i+3 DOWNTO 4*i));
END GENERATE;

--Complemento a 9 de 'y'
--en funcin de 'add_sub'

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);

--seal que utilizamos si el carry de


--de salida es 0, resultado negativo

- 74 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


b1_iteration: FOR i IN 0 TO n-1 GENERATE
nine_compl_2: nine_complement PORT MAP(
e => z1(4*i+3 DOWNTO 4*i),
add_sub => add_sub,
s => z2(4*i+3 DOWNTO 4*i));
END GENERATE;

--bloque que complementa a 9


--cuando el resultado
--anterior sea negativo

carries2(0) <= '0';


b2_iteration: FOR i IN 0 TO n-1 GENERATE
addition_2: one_digit_adder PORT MAP(
a => z2(4*i+3 DOWNTO 4*i),
b => i1(4*i+3 DOWNTO 4*i),
c => z3(4*i+3 DOWNTO 4*i),
cy_in => carries2(i),
cy_out => carries2(i+1));
END GENERATE;

--bloque utilizado para


--sumar 1 en BCD al
--complemento a nueve
--generado antes

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 operacin es suma: carry_out = '0' => resultado exacto
--Si la operacin es suma: carry_out = '1' => hay desbordamiento,
--aadir un '1' a la izquierda
--Si la operacin es resta: carry_out = '0' => resultado no negativo
--Si la operacin es resta: carry_out = '1' => resultado negativo
END architecture_nas;

5.1.4 Multiplicador de 1x1 dgitos BCD (one_digit_multiplier.vhd)


-----------------------------------------------------------------------Entidad del multiplicador de 1 dgito 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
a: IN
STD_LOGIC_VECTOR(3
b: IN
STD_LOGIC_VECTOR(3
d: OUT
STD_LOGIC_VECTOR(3
u: OUT
STD_LOGIC_VECTOR(3
END one_digit_multiplier;

PORT(
DOWNTO
DOWNTO
DOWNTO
DOWNTO

0);
0);
0);
0));

--entrada de 1 dgito BCD


--entrada de 1 dgito BCD
--salida de 1 dgito BCD
--salida de 1 dgito BCD

-----------------------------------------------------------------------Arquitectura del multiplicador de 1 dgito 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

- 75 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


--Declaracin de seales
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)));
gt20 <= uu(4) AND (uu(3) OR uu(2));
gt10st19 <= gt9 AND NOT(gt20);

--mayor a 9
--mayor a 19
--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 dgitos BCD (n_by_one_multiplier.vhd)


-----------------------------------------------------------------------Entidad del multiplicador de Nx1 dgitos 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);
y: IN
STD_LOGIC_VECTOR(3 DOWNTO 0);
z: OUT STD_LOGIC_VECTOR(4*n+3 DOWNTO 0));
END n_by_one_multiplier;

--entrada de n dgitos BCD


--entrada de 1 dgito BCD
--salida de n dgitos BCD

-----------------------------------------------------------------------Arquitectura del multiplicador de Nx1 dgitos 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
--Declaracin de seales
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);

- 76 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal


--Declaracin de componentes
COMPONENT one_digit_multiplier
a: IN
STD_LOGIC_VECTOR(3
b: IN
STD_LOGIC_VECTOR(3
d: OUT
STD_LOGIC_VECTOR(3
u: OUT
STD_LOGIC_VECTOR(3
END COMPONENT;

IS PORT(
DOWNTO 0);
DOWNTO 0);
DOWNTO 0);
DOWNTO 0));

Anexos

--entrada de 1 dgito BCD


--entrada de 1 dgito BCD
--salida de 1 dgito BCD
--salida de 1 dgito BCD

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;

- 77 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Anexos

5.1.6 Multiplicador de NxM dgitos BCD (n_by_m_multiplier.vhd)


-----------------------------------------------------------------------Entidad del multiplicador de N x M dgitos 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 dgitos BCD
y: IN STD_LOGIC_VECTOR(4*m-1 DOWNTO 0); --entrada de m dgitos BCD
start: IN STD_LOGIC;
--seal de inicio
clk:
IN STD_LOGIC;
--seal de reloj
reset: IN STD_LOGIC;
--inicializa la operacin
z: INOUT STD_LOGIC_VECTOR(4*(n+m)-1 DOWNTO 0); --salida de N+M
--dgitos BCD
done: OUT
STD_LOGIC);
--resultado disponible
END n_by_m_multiplier;
-----------------------------------------------------------------------Arquitectura del multiplicador de N x M dgitos 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
--Declaracin de estados
TYPE states IS RANGE 0 TO 3;
SIGNAL current_state: states;
--Declaracin de constantes
CONSTANT initial_zeroes: STD_LOGIC_VECTOR(4*m-5 DOWNTO 0) := (OTHERS =>
'0');
--Declaracin de seales
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;
--Declaracin de componentes
COMPONENT n_by_one_multiplier IS --multiplicador de Nx1 dgitos BCD
GENERIC (n:natural);
PORT(
x: IN
STD_LOGIC_VECTOR(4*n-1 DOWNTO 0);
--entrada de n dgitos BCD
y: IN
STD_LOGIC_VECTOR(3 DOWNTO 0);
--entrada de 1 dgito BCD
z: OUT STD_LOGIC_VECTOR(4*n+3 DOWNTO 0)); --salida de n dgitos BCD
END COMPONENT;

- 78 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


COMPONENT n_adder_subs IS
GENERIC (n:natural);
PORT(
x:
IN STD_LOGIC_VECTOR(4*n-1
y:
IN STD_LOGIC_VECTOR(4*n-1
add_sub: IN STD_LOGIC;
z:
OUT STD_LOGIC_VECTOR(4*n-1
carry_out: OUT STD_LOGIC);
END COMPONENT;

--Sumador/restador utilizado para sumar

DOWNTO 0); --entrada de n dgitos BCD


DOWNTO 0); --entrada de n dgitos BCD
--operacin: '0' suma y '1' resta
DOWNTO 0); --salida de n dgitos BCD
--acarreo de salida

--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;

adder: n_adder_subs
GENERIC MAP(n => n+m)
PORT MAP(
x => long_x_by_yi,
y => z_by_10,
add_sub => '0',
z => next_z);

--equiparamos las dos entradas


--del sumador en cuanto a
--nmero de dgitos

--operacin a realizar: suma

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);

- 79 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


--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 dgitos 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);
y:
IN
STD_LOGIC_VECTOR(4*n-1 DOWNTO 0);
start: IN
STD_LOGIC;
clk:
IN
STD_LOGIC;
reset: IN
STD_LOGIC;
q:
OUT STD_LOGIC_VECTOR(4*m-1 DOWNTO 0);
done: OUT STD_LOGIC);
END decimal_divider;

- 80 -

--dividendo
--divisor
--seal de inicio
--seal de reloj
--inicializa operacin
--resultado (cociente)
--operacin realizada

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Anexos

-----------------------------------------------------------------------Arquitectura del divisor de n dgitos 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
--Declaracin de estados
TYPE states IS RANGE 0 TO 3;
SIGNAL current_state: states;
--Declaracin 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');
--Declaracin de seales
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);
--Declaracin de componentes
COMPONENT n_by_one_multiplier IS
--multiplicador de Nx1 dgitos BCD
GENERIC (n:natural);
PORT(
x: IN
STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dgitos BCD
y: IN
STD_LOGIC_VECTOR(3 DOWNTO 0);
--entrada de 1 dgito BCD
z: OUT STD_LOGIC_VECTOR(4*n+3 DOWNTO 0)); --salida de n dgitos BCD
END COMPONENT;
COMPONENT n_adder_subs IS
GENERIC (n:natural);
PORT(
x:
IN STD_LOGIC_VECTOR(4*n-1
y:
IN STD_LOGIC_VECTOR(4*n-1
add_sub: IN STD_LOGIC;
z:
OUT STD_LOGIC_VECTOR(4*n-1
carry_out: OUT STD_LOGIC);
END COMPONENT;

--Sumador/restador utilizado para sumar

DOWNTO 0); --entrada de n dgitos BCD


DOWNTO 0); --entrada de n dgitos BCD
--operacin: '0' suma y '1' resta
DOWNTO 0); --salida de n dgitos BCD
--acarreo de salida

--Inicio
BEGIN
yy <= "0000" & y;

--Aadimos un 0 decimal a 'y' para igualarla


--en nmero de dgitos 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

- 81 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


subtraction: n_adder_subs
GENERIC MAP(n => n+1)
PORT MAP(
x => rr,
y => yy,
add_sub => '1',
z => rr_y,
carry_out => c_out);

--Restador para realizar 2r - y

--2r
--Resta como operacin a realizar
--resultado de 2r-y

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
GENERIC MAP(n => p)
PORT MAP(
x => qq,
y => ulp,
add_sub => '0',
z => qq_ulp);

--Sumador para realizar qq + ulp

--Suma como operacin a realizar

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 dgitos ms significativos


--de qq

--Sentencias secuenciales
register_r: PROCESS(clk)
BEGIN
IF clk'EVENT AND clk = '1' THEN
IF load = '1' THEN r <= x;
ELSIF ce = '1' THEN r <= s1;
END IF;
END IF;
END PROCESS;

--El valor inicial de r es x


--Actualiza el valor de r

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;

- 82 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


--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 Aritmtica Decimal (arithmetic_unit.vhd)


-----------------------------------------------------------------------Entidad de la unidad aritmtica 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);
y:
IN
STD_LOGIC_VECTOR(4*n-1 DOWNTO 0);
operation: IN
STD_LOGIC_VECTOR(1 DOWNTO 0);
start:
IN
STD_LOGIC;
clk:
IN
STD_LOGIC;
reset:
IN
STD_LOGIC;
z:
OUT STD_LOGIC_VECTOR(8*n-1 DOWNTO 0);
done:
OUT STD_LOGIC);
END arithmetic_unit;

- 83 -

--operando x
--operando y
--operacin
--seal de inicio
--seal de reloj
--inicializa
--resultado
--operacin lista

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal

-----------------------------------------------------------------------Arquitectura de la unidad aritmtica 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
--Declaracin de seales
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;
--Declaracin de componentes
COMPONENT n_adder_subs IS
GENERIC (n:natural);
PORT(
x:
IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dgitos BCD
y:
IN STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --entrada de n dgitos BCD
add_sub: IN STD_LOGIC;
--operacin: '0' suma y '1' resta
z:
OUT STD_LOGIC_VECTOR(4*n-1 DOWNTO 0); --salida de n dgitos 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 dgitos BCD
y: IN STD_LOGIC_VECTOR(4*m-1 DOWNTO 0); --entrada de m dgitos BCD
start: IN STD_LOGIC;
--seal de inicio
clk:
IN STD_LOGIC;
--seal de reloj
reset: IN STD_LOGIC;
--inicializa la operacin
z: INOUT STD_LOGIC_VECTOR(4*(n+m)-1 DOWNTO 0); --salida de N+M
--dgitos 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);
y:
IN
STD_LOGIC_VECTOR(4*n-1 DOWNTO 0);
start: IN
STD_LOGIC;
clk:
IN
STD_LOGIC;
reset: IN
STD_LOGIC;
q:
OUT STD_LOGIC_VECTOR(4*m-1 DOWNTO 0);
done: OUT STD_LOGIC);
END COMPONENT;

--dividendo
--divisor
--seal de inicio
--seal de reloj
--inicializa operacin
--resultado (cociente)
--operacin realizada

--Inicio
BEGIN
start1 <= start AND NOT(operation(0)) AND operation(1);
start2 <= start AND operation(0) AND operation(1);

- 84 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal


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;

- 85 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal

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
signal
signal
signal

jaddr : std_logic_vector( 8 downto 0 ) ;


jdata : std_logic_vector( 7 downto 0 ) ;
juser1 : std_logic ;
jwrite : std_logic ;

attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute

INIT_00
INIT_01
INIT_02
INIT_03
INIT_04
INIT_05
INIT_06
INIT_07
INIT_08
INIT_09
INIT_0A
INIT_0B
INIT_0C
INIT_0D
INIT_0E
INIT_0F
INIT_10
INIT_11
INIT_12
INIT_13
INIT_14
INIT_15
INIT_16
INIT_17
INIT_18
INIT_19
INIT_1A
INIT_1B

:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:

string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string
string

;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
;
- 86 -

Anexos

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute
attribute

INIT_1C : string ;
INIT_1D : string ;
INIT_1E : string ;
INIT_1F : string ;
INIT_20 : string ;
INIT_21 : string ;
INIT_22 : string ;
INIT_23 : string ;
INIT_24 : string ;
INIT_25 : string ;
INIT_26 : string ;
INIT_27 : string ;
INIT_28 : string ;
INIT_29 : string ;
INIT_2A : string ;
INIT_2B : string ;
INIT_2C : string ;
INIT_2D : string ;
INIT_2E : string ;
INIT_2F : string ;
INIT_30 : string ;
INIT_31 : string ;
INIT_32 : string ;
INIT_33 : string ;
INIT_34 : string ;
INIT_35 : string ;
INIT_36 : string ;
INIT_37 : string ;
INIT_38 : string ;
INIT_39 : string ;
INIT_3A : string ;
INIT_3B : string ;
INIT_3C : string ;
INIT_3D : string ;
INIT_3E : string ;
INIT_3F : string ;
INITP_00 : string ;
INITP_01 : string ;
INITP_02 : string ;
INITP_03 : string ;
INITP_04 : string ;
INITP_05 : string ;
INITP_06 : string ;
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"

- 87 -

;
;
;
;
;
;
;
;

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


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 ),

- 88 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Anexos

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
data_in:
ext_clk:
reset:
synch:
lcd_data:
lcd_e:
lcd_rs:
lcd_rw:
END main;

IS PORT(
IN STD_LOGIC_VECTOR(3 DOWNTO 0);
IN STD_LOGIC;
IN STD_LOGIC;
IN STD_LOGIC;
OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
OUT STD_LOGIC;
OUT STD_LOGIC;
OUT STD_LOGIC);

-----------------------------------------------------------------------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
--Declaracin 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;

- 89 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal

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(
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;

--Interfaz LCD

COMPONENT arithmetic_unit IS
--Unidad aritmtica 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);
--operacin
start:
IN
STD_LOGIC;
--seal de inicio
clk:
IN
STD_LOGIC;
--seal de reloj
reset:
IN
STD_LOGIC;
--inicializa
z:
OUT STD_LOGIC_VECTOR(8*n-1 DOWNTO 0); --resultado
done:
OUT STD_LOGIC);
--operacin lista
END COMPONENT;
--Declaracin de seales
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;

- 90 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Anexos

--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;

- 91 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal


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;

- 92 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


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;

- 93 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal

5.2 Programa en lenguaje ensamblador (decimal_unit.asm)


VHDL "my_ROM_blank.vhd", "program_memory.vhd", "program_memory"
;direcciones de entrada
z0
z1
z2
z3
z4
z5
z6
z7
z8
z9
z10
z11
z12
z13
z14
z15
synch
data_in
ready
done

DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN
DSIN

$00
$01
$02
$03
$04
$05
$06
$07
$08
$09
$0a
$0b
$0c
$0d
$0e
$0f
$10
$11
$12
$13

;direcciones de salida
y0
y1
y2
y3
y4
y5
y6
y7
x0
x1
x2
x3
x4
x5
x6
x7
temp_wr
id_write
start
operation

DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT
DSOUT

$00
$01
$02
$03
$04
$05
$06
$07
$08
$09
$0a
$0b
$0c
$0d
$0e
$0f
$10
$11
$12
$13

;registros internos
acc
address
data
command
counter

EQU
EQU
EQU
EQU
EQU

s0
s1
s2
s3
s4

- 94 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal


;main program
begin:
load command, $01
call lcd_control
load command, $80
call lcd_control

load address, $0f


first:
call wait_for_synch
in data, data_in
out data, address
call encode_data
call lcd_data
sub address, $01
jump NC, first
;addition
call wait_for_synch
load data, $00
out data, operation
call display_z
;end of addition
;substraction
call wait_for_synch
load data, $01
out data, operation
call display_z
;end of substraction
;multiplication
call wait_for_synch
load data, $02
out data, operation
out data, start
call wait_for_done
call display_z
;end of multiplication
;division
call wait_for_synch
load data, $03
out data, operation
out data, start
call wait_for_done
call display_z
;end of division
call wait_for_synch
jump begin
;end of main program

Anexos

;send command 01 (clear) to display,


;borramos el display
;send command 80 (cursor address = 00) to
;display, situamos el cursor al inicio de
;la primera fila
;initial address = 15
;escribimos los 16 dgitos de entrada, 8
;para 'x' y 8 para 'y'
;wait for a positive edge on synch
;store data_in in data
;write data into x(address)
;data = ASCII code
;display character data
;update address
;check whether address < 0

;wait for a positive edge on synch


;operation = 00
;display x+y

;wait for a positive edge on synch


;operation = 01
;display x-y

;wait for a positive edge on synch


;operation = 10
;start computation
;display x*y

;wait for a positive edge on synch


;operation = 11
;start computation
;display x/y

;wait for a positive edge on synch

- 95 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Anexos

;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
call encode_data
call lcd_data
sub address, $01
jump NC, first_bis
ret

;read z(address)
;data = ASCII code
;display character data
;update address
;check whether address < 0

;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

- 96 -

Anexos

Diseo sobre FPGA de una Unidad Aritmtica Decimal

;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 Asignacin de pines en la Spartan-3E (pins.ucf)


NET
NET
NET
NET
NET
NET

"ext_clk" LOC = "C9" | IOSTANDARD = LVCMOS33 ;


"reset" LOC = "K17" | IOSTANDARD = LVTTL | PULLDOWN ;
"data_in<3>" LOC = "N17" | IOSTANDARD = LVTTL | PULLUP
"data_in<2>" LOC = "H18" | IOSTANDARD = LVTTL | PULLUP
"data_in<1>" LOC = "L14" | IOSTANDARD = LVTTL | PULLUP
"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 ;

- 97 -

Diseo sobre FPGA de una Unidad Aritmtica Decimal

6. BIBLIOGRAFA

Diseo sobre FPGA de una Unidad Aritmtica Decimal

Bibliografa

6. Bibliografa
[1]

Serafn Alfonso Prez, Enrique Soto, Santiago Fernndez, Diseo de Sistemas Digitales con VDHL,
Editorial Thomson, 2002.

[2]

Fernando Pardo Carpio, Jos A. Boluda Grau, VHDL: Lenguaje para sntesis y modelado de
circuitos, Editorial Ra-Ma, 1999.

[3]

John F. Wakerly, Diseo digital. Principios y prcticas, Tercera edicin, Editorial Prentice Hall,
2001.

[4]

Thomas L. Floyd, Fundamentos de sistemas digitales, Novena edicin, 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]

Electrnica Digital I, apuntes de la asignatura.

[9]

ModelSim Users 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/

- 99 -

Вам также может понравиться