You are on page 1of 58

VHDL

wdgs21

PDF generado usando el kit de herramientas de fuente abierta mwlib. Ver http://code.pediapress.com/ para mayor informacin. PDF generated at: Sat, 19 Jan 2013 01:42:04 UTC

Contenidos
Artculos
Programacin en VHDL Introduccin Elementos bsicos del lenguaje Entidad Arquitectura Organizacin del cdigo Otros conceptos Bancos de pruebas Ejemplos Puerta triestado Multiplexor Sumador Contador Biestable-Latch Mquinas de estados ALU Apndices Sntesis Instalacin y uso de GHDL Bibliografa 1 2 6 12 14 22 28 30 37 37 38 39 40 41 43 45 46 46 51 53

Referencias
Fuentes y contribuyentes del artculo Fuentes de imagen, Licencias y contribuyentes 54 55

Licencias de artculos
Licencia 56

Programacin en VHDL

Programacin en VHDL

Programacin en VHDL
ndice de contenidos
1. 2. 3. 4. Introduccin Capitulo 1: Elementos bsicos del lenguaje Captulo 2: Entidad Captulo 3: Arquitectura

1. Descripcin de flujo de datos 2. Descripcin de comportamiento 3. Descripcin estructural 5. Captulo 4: Organizacin del cdigo 6. Captulo 5: Otros conceptos 7. Captulo 6: Bancos de pruebas 8. Captulo 7: Ejemplos 1. 2. 3. 4. 5. 6. 7. Puerta triestado Multiplexor Sumador Contador Biestable-Latch Mquinas de estados ALU

Apndices 1. Sntesis 2. Instalacin y uso de GHDL Bibliografa

Introduccin

Introduccin
Descripcin
VHDL significa VHSIC Hardware Description Language, y a su vez VHSIC significa Very High Speed Integrated Circuit. Se trata de un lenguaje de descripcin de hardware, esto significa que mediante l se puede describir la forma de comportarse de un circuito electrnico. El comportamiento puede ser llevado a algn dispositivo que dispondr de sus propios componentes con los que lograr ese comportamiento deseado. La forma de comportarse es independiente del hardware donde se implementar. El VHDL es un estndar llamado IEEE 1076-1993. Sus ventajas son: Una disponibilidad pblica Independencia de dispositivos y fabricantes Reutilizacin Diseo jerrquico

Un proyecto de VHDL puede contener muchos ficheros. El cdigo VHDL usualmente se encuentra en los ficheros con extensin *.vhd. La estructura tpica de uno de estos ficheros es: Llamadas a libreras Entidad Arquitectura(s)

Historia
A mediados de los aos setenta se produce una fuerte evolucin en los procesos de fabricacin de los circuitos integrados, y junto a las tecnologas bipolares, surge la tecnologa MOS (metal oxide semiconductor ), principalmente la NMOS, promoviendo el desarrollo de circuitos digitales hasta la primera mitad de los aos ochenta. En aquellas pocas, el esfuerzo de diseo se concentraba en los niveles elctricos para establecer caractersticas e interconexiones entre los componentes bsicos a nivel de transistor. El proceso de diseo era altamente manual y tan solo se empleaban herramientas como el PSPICE para simular esquemas elctricos con modelos previamente personalizados a las distintas tecnologas. A medida que pasaban los aos, los procesos tecnolgicos se hacan ms y ms complejos. Los problemas de integracin iban en aumento y los diseos eran cada vez ms difciles de depurar y de dar mantenimiento. Inicialmente los circuitos MSI (Medium Scale Integration ) y LSI (Low Scale Integration ) se disearon mediante la realizacin de prototipos basados en mdulos ms sencillos. Cada uno de estos mdulos estaba formado por puertas ya probadas, este mtodo poco a poco, iba quedndose obsoleto. En ese momento (finales de los aos setenta) se constata el enorme desfase que existe entre tecnologa y diseo. La considerable complejidad de los chips que se pueden fabricar, implica unos riesgos y costes de diseo desmesurados e imposibles de asumir por las empresas. Es entonces, cuando diversos grupos de investigadores empiezan a crear y desarrollar los llamados "lenguajes de descripcin de hardware" cada uno con sus peculiaridades. Empresas tales como IBM con su IDL, el TI - HDL de Texas Instruments, ZEUS de General Electric, etc., as como los primeros prototipos empleados en las universidades, empezaron a desarrollarse buscando una solucin a los problemas que presentaba el diseo de los sistemas complejos. Sin embargo, estos lenguajes nunca alcanzaron el nivel de difusin y consolidacin necesarios por motivos distintos. Unos, los industriales, por ser propiedad de la empresa permanecieron encerrados en ellas y no estuvieron disponibles par su estandarizacin y mayor difusin, los otros, los universitarios, perecieron por no disponer de soporte ni mantenimiento adecuado. Alrededor de 1981 el Departamento de Defensa de los Estados Unidos desarrolla un proyecto llamado VHSIC (Very High Speed

Introduccin Integrated Circuit ) su objetivo era rentabilizar las inversiones en hardware haciendo ms sencillo su mantenimiento. Se pretenda con ello resolver el problema de modificar el hardware diseado en un proyecto para utilizarlo en otro, lo que no era posible hasta entonces porque no exista una herramienta adecuada que armonizase y normalizase dicha tarea, era el momento de los HDL's VHDL En 1983, IBM, Intermetrics y Texas Instruments empezaron a trabajar en el desarrollo de un lenguaje de diseo que permitiera la estandarizacin, facilitando con ello, el mantenimiento de los diseos y la depuracin de los algoritmos, para ello el IEEE propuso su estndar en 1984. Tras varias versiones llevadas a cabo con la colaboracin de la industria y de las universidades, que constituyeron a posteriori etapas intermedias en el desarrollo del lenguaje, el IEEE public en diciembre de 1987 el estndar IEEE std 1076-1987 que constituy el punto firme de partida de lo que despus de cinco aos sera ratificado como VHDL. Esta doble influencia, tanto de la empresa como de la universidad, hizo que el estndar asumido fuera un compromiso intermedio entre los lenguajes que ya haban desarrollado previamente los fabricantes, de manera que ste qued como ensamblado y por consiguiente un tanto limitado en su facilidad de utilizacin haciendo dificultosa su total comprensin. Este hecho se ha visto incluso ahondado en su revisin de 1993. Pero esta deficiencia se ve altamente recompensada por la disponibilidad pblica, y la seguridad que le otorga el verse revisada y sometida a mantenimiento por el IEEE. La independencia en la metodologa de diseo, su capacidad descriptiva en mltiples dominios y niveles de abstraccin, su versatilidad para la descripcin de sistemas complejos, su posibilidad de reutilizacin y en definitiva la independencia de que goza con respecto de los fabricantes, han hecho que VHDL se convierta con el paso del tiempo en el lenguaje de descripcin de hardware por excelencia...

Otras alternativas
ABEL
Abreviatura de Advanced Boolean Expression Language. ABEL permite describir diseos mediante tablas de verdad o ecuaciones lgicas. Tambin permite la programacin secuencial con mquinas de estados.

AHDL
Abreviatura de Altera Hardware Description Language (Lenguaje de Descripcin de Hardware de Altera). Este lenguaje hardware es propietario de Altera Corporation para la programacin de CPLDs y FPGAs. Destacar que este lenguaje tiene una sintaxis similar a C, pero su funcionalidad es parecida a la del VHDL.

Verilog
Es la gran alternativa al VHDL. Tuvo gran aceptacin por parte de los ingenieros, puesto que la sintaxis de este lenguaje es muy parecida a la del lenguaje de programacin C.

Otros
La ltima tendencia en los lenguajes de descripcin de hardware es parecerse cada vez ms a los lenguajes informticos ms habituales, como C o C++. El objetivo de estos lenguajes es que la descripcin de un algoritmo sea nica, independientemente de la plataforma destino (PC, FPGA, ASIC, etc). Los ms destacados son BachC, Handel-C y SystemC.

Introduccin

Tipos de descripcin
Como se ha dicho antes, VHDL sirve para describir un circuito electrnico, pero el mismo circuito puede ser descrito de varias formas. Las formas de hacerlo son: Descripcin de comportamiento Descripcin de flujo de datos (RTL Registred Transfer Level) Descripcin estructural A continuacin se presenta una descripcin de cada tipo de descripcin y un ejemplo en VHDL, obviamente an no se ha visto la sintxis de VHDL por lo que habr partes del cdigo que el lector no pueda entender. El cdigo se pone slo para poder comparar las distintas formas de descripcin. Los tres ejemplos de cdigo son slo las arquitecturas, los tres podran tener como entidad: ENTITY mux PORT(control, entrada1, entrada2: IN BIT; salida: OUT BIT); END mux;

Descripcin de comportamiento
Una descripcin de comportamiento de un multiplexor de dos entradas, una salida y una seal de seleccin sera: la salida ser igual a la primera entrada si la seal de control est desactivada y la salida ser la segunda entrada si la seal de control est activada. En VHDL la arquitectura de este multiplexor para la entidad llamada mux sera: ARCHITECTURE mux_comportamiento OF mux IS BEGIN PROCESS(entrada1, entrada2, control) BEGIN IF(control = '0') THEN salida <= entrada1; ELSE salida <= entrada2; END IF; END PROCESS; END mux_comportamiento;

Descripcin de flujo de datos


En una descripcin de flujo de datos del mismo multiplexor la salida sera la ecuacin lgica: s=(entrada1 AND NOT control) OR (entrada2 AND control) En VHDL la arquitectura sera: ARCHITECTURE mux_rtl OF mux IS SIGNAL int1, int2, int3 : BIT; BEGIN int1 <= NOT control; int2 <= entrada1 AND int1; int3 <= entrada2 AND control;

Introduccin salida <= int2 OR int3; END mux_rtl; Esta descripcin hay varias instrucciones concurrentes, por lo que son ejecutadas cada vez que una seal interviene en su asignacin. Realmente, se trata casi de una descripcin estructural, puesto que se estn describiendo seales y sus componentes. Aunque tambin son asignaciones a seales y no una lista de componentes y sus conexiones. En el siguiente ejemplo se muestra una descripcin de flujo de datos pura. ARCHITECTURE mux_rtl OF mux IS BEGIN salida <= entrada1 WHEN control = '0' ELSE entrada2; END mux_rtl;

Descripcin estructural
Una descripcin estructural consistira en decir que el circuito tiene una puerta inversora U1, dos puertas AND de dos entradas U2 y U3 y una puerta lgica OR de dos entradas U4, adems tambin describe las conexiones entre estas puertas, un ejemplo sera: la entrada de U1 es la seal de control, la salida de U1 se conecta a la segunda entrada de U2, la primera entrada de U1 es entrada1, etc. El cdigo VHDL sera: ARCHITECTURE mux_estructural OF mux IS SIGNALl int1, int2,int3:bit; BEGIN U1: inversor PORT MAP(control, int1); U2: and_2_entradas PORT MAP(entrada1, int1, int2); U3: and_2_entradas PORT MAP(entrada2, control, int3); U4: or_2_entradas PORT MAP(int2, int3, salida); END mux_estructural; En el cdigo anterior se deberan haber definido previamente las puertas inversor, and_2_entradas y or_2_entradas.

Elementos bsicos del lenguaje

Elementos bsicos del lenguaje


Antes de comenzar es preciso conocer algunos elementos bsicos del lenguaje VHDL.

Comentarios
Los comentarios van precedidos de dos guiones. En una lnea se ignorar todo aquello que vaya despus de dos guiones seguidos. Ejemplo: -- Esto es un comentario

Identificadores
Son cualquier cadena de caracteres que sirven para identificar variables, seales, procesos, etc. Puede ser cualquier nombre compuesto por letras (aux) o nmeros y letras (aux1, aux2, aux3, ...), incluyendo el smbolo de subrayado "_". Las maysculas y minsculas son consideradas iguales, por lo tanto los identificadores TMP y tmp representan el mismo elemento. No es posible crear un identificador que coincida con alguna palabra reservada del lenguaje.

Nmeros
Cualquier nmero se representa en base 10. Aunque es posible poner los nmeros en otras bases utilizando diferentes smbolos, como se muestra en la siguiente seccin.

Bases
Para escribir un nmero se puede hacer en binario, octal, decimal y hexadecimal. Para vectores de bits: "01111" binario O"17" octal X"F" hexadecimal Para enteros y reales: 2#1100# binario 12 decimal 16#C# hexadecimal l

Tipos de datos
Como en cualquier lenguaje de programacin existen varios tipos de datos, en VHDL se pueden diferenciar dos: escalares y compuestos.

Tipos escalares
Son tipos simples que contienen algn tipo de magnitud. Enteros: Son datos con un valor numrico entero. La forma de definirlos es con la palabra RANGE. Realmente se dice que un nmero est en un lmite establecido. TYPE byte IS RANGE 0 TO 255; Fsicos: Se trata de datos que corresponden con magnitudes fsicas, que tienen un valor y unas unidades.

Elementos bsicos del lenguaje TYPE longitud IS RANGE 0 TO 1.0e9 UNITS um; mm=1000 um; m=1000 mm; in=25.4 mm; END UNITS; Reales o coma flotante: Se definen igual que los enteros con la diferencia que los lmites son nmeros reales. TYPE nivel IS RANGE 0.0 TO 5.0 Enumerados: Son datos que puede tomar siempre que se encuentre en una lista o conjunto finito. Es idntico a las enumeraciones en C (enum). TYPE color IS (ROJO, VERDE, AMARILLO);

Tipos compuestos
Son tipos de datos compuestos por los que se han visto anteriormente. Matrices: Se trata de un conjunto de elementos del mismo tipo, accesibles mediante un ndice. Los hay de dos tipos: monodimensionales o multidimensionales. TYPE word IS ARRAY (31 DOWNTO 0) OF bit; TYPE tabla IS ARRAY (1 TO 4, 1 TO 4) OF real; En este punto es necesario explicar la palabra reservada OTHERS, donde es posible asignar un determinado valor a todos los elementos de la matriz. word <= (OTHERS => '0'); -- Asigna '0' en todas las posiciones

Las palabras reservadas TO y DOWNTO sirven para indicar los ndices de una matriz. El primero indica un rango ascendente (de x a y), mientras que el segundo es descendente (desde x hasta y). -- word1 y word2 son elementos idnticos TYPE word1 IS ARRAY (31 DOWNTO 0) OF bit; TYPE word2 IS ARRAY (0 TO 31) OF bit; Dependiendo de la opcin elegida el bit ms significativo corresponder al primer bit (0) o al ltimo (31). Tambin es posible obtener un trozo de una matriz para poder realizar operaciones con ella. TYPE word IS ARRAY (31 DOWNTO 0) OF bit; TYPE subword IS ARRAY (7 DOWNTO 0) OF bit; ... subword <= word(31 DOWNTO 24); Adems, es posible asignar a una matriz una lista separada por comas, de forma que el primer elemento de la lista corresponde al primero de la matriz. semaforo <= (apagado, apagado, encendido); luces <= (apagado, verde, azul, ..., amarillo); Registros: Es equivalente al tipo record de otros lenguajes.

Elementos bsicos del lenguaje TYPE trabajador IS RECORD nombre : string; edad : integer; END RECORD; Para acceder a algn atributo del registro se utilizar el punto. trabajadorA.nombre="Juan"

Subtipos de datos
En VHDL se pueden definir subtipos, los cuales corresponden a tipos ya existentes. Se pueden diferenciar dos tipos dependiendo de las restricciones que se apliquen. Restricciones de un tipo escalar a un rango: SUBTYPE indice IS integer RANGE 0 TO 7; SUBTYPE digitos IS character RANGE '0' TO '9'; Restricciones del rango de una matriz: SUBTYPE id IS string(0 TO 15); SUBTYPE dir IS bit_vector(31 DOWNTO 0); La ventaja de utilizar subtipos se basa a la hora de sintetizar un circuito, ya que si se utiliza el propio tipo, como puede ser el integer, se interpretar como un bus de 32 lneas, pero realmente slo harn falta muchas menos.

Conversin de tipos
En ocasiones puede ser necesario convertir unos tipos a otros, esta operacin es conocida como casting. Algunas de las conversiones son automticas, como puede ser el paso de entero a real, otras conversiones deben realizarse de forma explcita, indicando el nombre del tipo al que se quiere pasar seguido del valor entre parntesis. real(15); integer(3.5); En muchos diseos es necesario realizar conversiones entre bits y enteros. A continuacin se muestran varias funciones de conversin entre ambos tipos.
conv_integer(std_logic_vector); -- Conversin de vector a entero conv_std_logic_vector(integer, numero_bits); -- Conversin de entero a vector de numero_bits de tamao

Constantes, seales y variables


En VHDL existen tres tipos de elementos: seales, constantes y variables. Estas dos ltimas tienen un significado similar a cualquier otro lenguaje de programacin. Todos estos elementos son diferentes. Las variables slo tienen sentido dentro de los procesos o subprogramas, mientras que las seales pueden ser declaradas en arquitecturas, paquetes o bloques concurrentes. Las constantes pueden ser declaradas en los mismos sitios que las variables y seales.

Elementos bsicos del lenguaje

Constantes
Es un elemento que se inicializa con un valor determinado, el cual no puede ser modificado, es decir siempre conserva el mismo valor. Esto se realiza con la palabra reservada CONSTANT. CONSTANT e : real := 2.71828; CONSTANT retraso : time := 10 ns; Tambin es posible no asociar un valor a una constante, siempre que el valor sea declarado en otro sitio. CONSTANT max : natural;

Variables
Es lo mismo que una constante, pero con la diferencia que puede ser modificada en cualquier instante, aunque tambin es posible inicializarlas. La palabra reservada VARIABLE es la que permite declarar variables. VARIABLE contador : natural := 0; VARIABLE aux : bit_vector(31 DOWNTO 0); Es posible, dado un elemento cambiarle el nombre o ponerle nombre a una parte mediante la palabra reservada ALIAS. VARIABLE instruccion : bit_vector(31 DOWNTO 0); ALIAS cod_op : bit_vector(7 DOWNTO 0) IS instruccion(31 DOWNTO 24);

Seales
Las seales se declaran con la palabra reservada SIGNAL, a diferencia con las anteriores este tipo de elementos pueden ser de varios tipos: normal, register o bus. Es posible asignarles un valor inicial. SIGNAL sel : bit := '0'; SIGNAL datos : bit_vector(7 DOWNTO 0);

Atributos
Los elementos como seales y variables pueden tener atributos, stos se indican a continuacin del nombre, separados con una comilla simple "'" y pueden incluir informacin adicional de algunos objetos desarrollados en VHDL, que servirn a las herramientas de diseo para obtener informacin a la hora de realizar una sntesis. Existen muchos atributos, como LEFT, RIGHT, LOW, HIGH, RANGE, LENGTH... Pero el atributo ms usado es EVENT, que indica si una seal ha cambiado de valor. Por ejemplo la siguiente sentencia captura un flanco de subida de una seal (clk). .... if clk'event and clk = '1' then ....

Elementos bsicos del lenguaje

10

Definicin de atributos
Un atributo definido por el diseador siempre devolver un valor constante. En primer lugar se debe declarar el atributo, mediante la palabra reservada ATTRIBUTE, indicando el tipo de elemento que se devuelve, seguidos el valor que se retornar. La sintaxs para definir atributos sera la siguiente. ATTRIBUTE nombre : tipo ATTRIBUTE nombre OF id_elemento : clase IS valor Donde nombre es el identificador del atributo, id_elemento corresponde al identificador de un elemento del lenguaje definido previamente (seal, variable, etc.), la clase es el tipo de elemento al que se le va aadir dicho atributo, es decir si es seal, constante, etc. y el valor ser lo que devuelva al preguntar por dicho atributo. Un ejemplo de todo esto puede ser el siguiente. SIGNAL control : std_logic; ATTRIBUTE min : integer; ATTRIBUTE min OF control : SIGNAL IS 4; .... IF control'min > 20 THEN

Operadores
Los operadores que proporciona el lenguaje son: Lgicos: Actan sobre los tipos bit, bit_vector y boolean. En el caso de utilizar este tipo de operadores en un vector, la operacin se realizar bit a bit. Operadores: AND, OR, NAND, NOR, XOR, XNOR y NOT. Aritmticos: + (suma o signo positivo): Sirve para indicar una suma entre dos nmeros. Tambin puede actuar como smbolo si se sita delante de una expresin. - (resta o signo negativo): Sirve para indicar la resta entre dos nmeros. Si va delante de una expresin modifica el signo de la expresin. * (multiplicacin): Multiplica dos nmeros de cualquier tipo. / (divisin): Divide dos nmeros de cualquier tipo. ** (exponencial): Eleva un nmero a una potencia. El nmero de la izquierda puede ser entero y real, pero el de la derecha slo puede ser entero. Ejemplo: 4**2 sera 4. ABS() (valor absoluto): Devuelve el valor absoluto de su argumento. MOD (mdulo): Calcula el mdulo de dos nmeros. REM (resto): Calcula el resto de la divisin. Relacionales: Siempre devuelven un valor booleano (true o false). ==, /= (igualdad): El primero devuelve verdadero si los operando son iguales y falso en caso contrario. El segundo indica desigualdad, funcionando al revs que el anterior. >, >=, <, <= (menor mayor): Poseen el significado habitual (mayor que, mayor o igual que, menor que, menor o igual que, respectivamente). La diferencia con los anteriores reside en su uso, en este caso los tipos de datos que pueden manejar son siempre de tipo escalar o matrices. Desplazamientos: (incluidas en la revisin de 1993) SLL (Shift Left Logic) y SRL (Shift Right Logic), desplazamiento lgico a la izquierda y desplazamiento lgico a la derecha, respectivamente, rellenando de ceros los huecos.

Elementos bsicos del lenguaje SLA (Shift Left Arithmetic) y SRA (Shift Right Arithmetic), desplazamiento aritmtico a la izquierda y derecha respectivamente. ROL (ROtate Left) y ROR (ROtate Right), rotacin a la izquierda y a la derecha respectivamente. En este caso los huecos son ocupados por los bits que van quedando fuera. A continuacin se muestran ejemplos sobre los operadores de desplazamiento:
-- Inicialmente a vale 1100 1101 a sll 4 -- El resultado es 1101 0000 a sla 4 -- El resultado es 1101 1111 (extensin del ltimo bit) a srl 4 -- El resultado es 0000 1100 a sra 4 -- El resultado es 1111 1100 a rol 4 -- El resultado es 1101 1100 (los primeros 4 bits pasan a la ltima posicin) a ror 4 -- El resultado es 1101 1100

11

Otros: & (concatenacin): Concatena vectores de manera que la dimensin de la matriz resultante es la suma de las dimensiones de las matrices con las que se opera. Hay que decir que no todos los operadores pueden funcionar sobre todos los tipos de datos. Tambin hay operadores que en determinadas circunstancias no pueden ser utilizados, por ejemplo al hacer cdigo sintetizable no es recomendable usar multiplicadores (excepto si uno de los operadores es potencia de dos, puesto que se tratara de un simple desplazamiento de bits). El orden de preferencia, de mayor a menor es: 1. 2. 3. 4. 5. 6. **, ABS, NOT *, /, MOD, REM +, - (signo) +, -, & (operaciones) =, /=, <, <=, >, >= AND, OR, NAND, NOR, XOR

Entidad

12

Entidad
Durante los captulos anteriores se ha insistido varias veces en que VHDL sirve para describir hardware. Un circuito electrnico puede ser parte de otro ms grande, en este caso el primero sera un subcircuito del segundo. Por lo tanto, un circuito puede estar compuesto por muchos subcircuitos y estos subcircuitos se interconectaran. As aparece una jerarqua en el diseo. En la parte alta de la jerarqua apareceran los circuitos ms complejos, que estaran compuestos por subcircuitos y, a su vez, cada uno de estos subcircuitos podra estar compuesto por subcircuitos ms sencillos. Un ejemplo de jerarqua sera un microprocesador. El circuito ms complejo y el ms alto en la jerarqua sera el propio microprocesador. ste estara compuestos por subcircuitos, por ejemplo el de la unidad de control, el de la unidad aritmtico-lgica, memorias, registros, etc. Estos subcircuitos estaran conectados por lneas elctricas, pueden ser simples como un cable o complejas como un bus. Una unidad de control estara compuesta por ms subcircuitos, ms registros, ms buses, etc. Cuando se est diseando en un determinado nivel, seguramente se empleen elementos de niveles ms bajos. Para usar estos elementos de nivel bajo en un nivel ms alto slo se necesita conocer su interfaz, es decir, sus entradas y salidas, sobre ellas se conectaran los cables o buses que correspondieran.

Declaracin de entidad
La entidad sirve para definir las entradas y salidas que tendr un determinado circuito. Para definir una entidad se realizar mediante la palabra reservada ENTITY. En principio pudiera parecer que esta definicin sea equivalente a la cabecera de una funcin de un lenguaje cualquiera de programacin. En VHDL es ms conveniente ver a la entidad como una caja negra con cables para las entradas y salidas. La ventaja de pensar en una entidad como en una caja negra a la que se conectan cables es que es ms fcil comprender la ejecucin concurrente que ocurrir en el hardware. La descripcin de cmo funciona por dentro esa caja negra es la arquitectura, que se ver en el siguiente captulo. A continuacin se muestra la sintxis de una entidad. ENTITY nombre IS [GENERIC(lista de parmetros);] [PORT(lista de puertos);] END [ENTITY] nombre; La instruccin GENERIC define y declara propiedades o constantes del mdulo. Las constantes declaradas en esta seccin son como los parmetros en las funciones de cualquier otro lenguaje de programacin, por lo que es posible introducir valores, en caso contrario tomar los valores por defecto. Para declarar una constante se indicar su nombre seguido de dos puntos y el tipo del que se trata, finalmente se indicar el valor al que es inicializado mediante el operador de asignacin :=. En el caso que existan ms constantes se terminar con un punto y coma, la ltima constante no lo llevar. nombre_constante : tipo := inicializacion; La instruccion PORT definen las entradas y salidas del mdulo definido. Basicamente consiste en indicar el nombre de la seal seguido de dos puntos y la direccin del puerto (se ver ms adelante), adems del tipo de seal del que se trata. Al igual que antes, si existe ms de una seal se finalizar con un punto y coma, exceptuando la ltima seal de la lista. nombre_seal : direccin tipo;

Entidad A continuacin se muestra un ejemplo de una entidad, con una serie de constantes y seales de entrada y salida. ENTITY mux GENERIC( C_AWIDTH C_DWIDTH ); PORT( control entrada1 entrada2 salida ); END mux;

13

: integer := 32; : integer := 32

: : : :

IN bit; IN bit; IN bit; OUT bit

En este ejemplo la entidad de llama mux. Su interfaz se compone de las seales control, entrada1 y entrada2 como entradas de tipo bit y de la seal llamada salida como salida, tambin de tipo bit. Adems, se incluyen dos constantes que servirn a la parte declarativa para realizar alguna operacin. En la introduccin se vio como asignar las seales de entradas y salidas mediante la palabra PORT MAP, para el caso de los genricos se realiza con la palabra reservada GENERIC MAP, esta parte se estudiar con mayor detalle en los siguientes captulos. Un ejemplo para utilizar el cdigo anterior como un componente sera el siguiente. mux_1 : ENTITY work.mux GENERIC MAP( C_AWIDTH => C_AWIDTH, C_DWIDTH => C_DWIDTH ) PORT MAP( control => control, entrada1 => entrada1, entrada2 => entrada2, salida => salida ); Obsrvese que en todo momento se habla de seales y no de variables, para el caso de los puertos.

Direcciones de los puertos de una entidad


Las seales representaran la funcin que haran los cables en un diseo hardware tradicional, es decir, sirven para transportar informacin y establecer conexiones. Dentro de una entidad los puertos son considerados como seales, en donde se pueden diferenciar varios tipos. IN: Son seales de entrada, las cuales slo se pueden leer, pero no se le pueden asignar ningn valor, es decir, no se puede modificar el valor que poseen. Por lo tanto, su funcionalidad es similar a las constantes. OUT: Corresponden a las seales de salida, en este caso su valor puede ser modificado, pero en este caso no pueden leerse, es decir no pueden ser utilizadas como argumentos en la asignacin de cualquier elemento. INOUT: Este tipo es una mezcla de los dos anteriores, pueden ser utilizados tanto como de lectura o de escritura. BUFFER: Es idntico al anterior, con la diferencia de que slo una fuente puede modificar su valor.

Arquitectura

14

Arquitectura
Como se ha dicho en el captulo anterior, la arquitectura es lo que define cmo se comporta un circuito. En el primer captulo tambin se mostraron varias arquitecturas en las que se describa un multiplexor. La primera lnea de cada una era ARCHITECTURE mux_comportamiento OF mux IS ARCHITECTURE mux_rtl OF mux IS ARCHITECTURE mux_estructural OF mux IS Los nombres de cada arquitectura son mux_comportamiento, mux_rtl y mux_estructural respectivamente. Todas estn asociadas a la entidad mux. El nombre de la arquitectura se usar para indicar qu arquitectura se debe usar en caso que haya varias para una misma entidad. Despus de esta lnea pueden aparecer varias instrucciones para indicar la declaracin de seales, componentes, funciones, etc.. Estas seales son internas, es decir, a ellas no se puede acceder desde la entidad, por los que los circuitos de nivel superior no podran acceder a ellas. En un smil con un microprocesador, estas seales podran ser las lneas que comunican la unidad central con la ALU, a las que no se puede acceder directamente desde el exterior del microprocesador. Obsrvese que en este caso no se indica si son entradas o salidas, puesto que al ser internas pueden ser ledas o escritas sin ningn problema. En esta parte de la arquitectura tambin pueden aparecer otros elementos, como pueden ser las constantes. Lo siguiente es la palabra clave BEGIN, que da paso a la descripcin del circuito, mediante una serie de sentencias. Por lo tanto, la sintxis de una arquitectura sera. ARCHITECTURE nombre OF nombre_entidad IS [declaraciones] BEGIN [sentencias concurrentes] END [ARCHITECTURE] [nombre]; Un ejemplo de una arquitectura podra ser la siguiente. ARCHITECTURE mux_rtl OF mux IS SIGNAL int1, int2, int3 : BIT; BEGIN int1 <= NOT control; int2 <= entrada1 AND int1; int3 <= entrada2 AND S; salida <= int2 OR int3; END mul_rtl; La descripcin puede ser de tres tipos: 1. Descripcin de flujo de datos 2. Descripcin de comportamiento 3. Descripcin estructural

Descripcin de flujo de datos


A la hora de plantearse crear un programa en VHDL no hay que pensar como si fuera un programa tpico para ordenador. No hay que olvidar que en VHDL hay que describir un hardware, algo que no se hace en un programa para ordenador. Un circuito electrnico puede tener muchos elementos que estn ejecutando acciones a la vez, por

Arquitectura ejemplo en un circuito puede tener una entrada que se aplique a dos puertas lgicas y de cada una obtener una salida, en este caso tendra dos caminos en los que se ejecutaran acciones (las puertas lgicas) de forma paralela. Esto es lo que se llama concurrencia. VHDL es un lenguaje concurrente, como consecuencia no se seguir el orden en que estn escritas las instrucciones a la hora de ejecutar el cdigo. De hecho, si hay dos instrucciones, no tiene porqu ejecutarse una antes que otra, pueden ejecutarse a la vez.

15

Sentencias Concurrentes
La instruccin bsica de la ejecucin concurrente es la asignacin entre seales a travs del smbolo <=. Para facilitar la asignacin de las seales VHDL incluye elementos de alto nivel como son instrucciones condicionales, de seleccin, etc, que se vern a continuacin. WHEN ... ELSE Sentencia de seleccin mltiple. En hardware es necesario incluir todas las opciones posibles. En este caso es obligatorio siempre acabar la expresin con un ELSE. <seal> <= <asignacin1> WHEN <condicin1> ELSE <asignacin2> WHEN <condicin2> ELSE ... <asignacinN> WHEN <condicinN> ELSE <asignacinM>; Un posible ejemplo de este tipo de sentencias podra ser la siguiente. s <= "00" WHEN a = b ELSE "01" WHEN a > b ELSE "11"; Siempre es obligatorio asignar algo, aunque es posible no realizar ninguna accin, para ello se utiliza la palabra reservada UNAFFECTED. De esta forma se asignar el mismo valor que tena la seal. s1 <= d1 WHEN control = '1' ELSE UNAFFECTED; s2 <= d2 WHEN control = '1' ELSE s2; Las dos sentencias anteriores parecen iguales, pero en la segunda se produce una transaccin, aspecto que en la primera no sucede. WITH ... SELECT ... THEN Es similar a las sentencias CASE o SWITCH de C. La asignacin se hace segn el contenido de un objeto o resultado de cierta expresin. WITH <seal1> SELECT <seal2> <= <asignacin1> WHEN <estado_seal1>, <asignacin2> WHEN <estado_seal2>, ... <asignacinN> WHEN OTHERS; Un ejemplo de esta sentencia es la siguiente.

Arquitectura

16

WITH estado SELECT semaforo <= "rojo" "verde" "amarillo" "roto"

WHEN WHEN WHEN WHEN

"01", "10", "11", OTHERS;

La clusula WHEN OTHERS especifica todos los dems valores que no han sido contemplados. Tambin es posible utilizar la opcin que se contempl en el caso anterior (UNAFFECTED). BLOCK En ocasiones interesa agrupar un conjunto de sentencias en bloques. Estos bloques permiten dividir el sistema en mdulos, estos mdulos pueden estar compuestos de otros mdulos. La estructura general es la siguiente. block_id; BLOCK(expresin de guardia) cabecera declaraciones BEGIN sentencias concurrentes END BLOCK block_id; El nombre del bloque es opcional (block_id), al igual que la expresin de guardia. Un ejemplo de esto podra ser el siguiente. latch: BLOCK(clk='1') BEGIN q <= GUARDED d; END BLOCK latch;

Descripcin de comportamiento
Como la programacin concurrente no siempre es la mejor forma de describir ideas, VHDL incorpora la programacin serie, la cual se define en bloques indicados con la sentencia PROCESS. En un mismo diseo puede haber varios bloques de este tipo, cada uno de estos bloques corresponder a una instruccin concurrente. Es decir, internamente la ejecucin de las instrucciones de los PROCESS es serie, pero entre los bloques es concurrente. A continuacin se vern la estructuras ms comunes de la ejecucin serie y sus caractersticas.

PROCESS
Un PROCESS, como se ha dicho antes, es una sentencia concurrente en el sentido de que todos los PROCESS y todas las dems sentencias concurrentes se ejecutarn sin un orden establecido. No obstante las sentencias que hay dentro del PROCESS se ejecutan de forma secuencial. Por lo tanto se puede decir que una estructura secuencial va en el interior de un PROCESS. La estructura genrica de esta sentencia es: PROCESS [lista de sensibilidad] [declaracin de variables] BEGIN [sentencias secuenciales]

Arquitectura END PROCESS; La lista de sensibilidad es una serie de seales que, al cambiar de valor, hacen que se ejecute el PROCESS. Un ejemplo sera: PROCESS(seal1, seal2) ... El PROCESS anterior slo se ejecutar cuando seal1 o seal2 cambien de valor.

17

Variables y Seales
Hay que distinguir las seales y las variables, las seales se declaran entre ARCHITECTURE y su correspondiente BEGIN mientras que las variables se declaran entre PROCESS y su BEGIN. Dentro de un PROCESS pueden usarse ambas, pero hay una diferencia importante entre ellas: las seales slo se actualizan al terminar el proceso en el que se usan, mientras que las variables se actualizan instantneamente, es decir, su valor cambia en el momento de la asignacin. Unos ejemplos son: ENTITY ejemplo PORT (c: IN std_logic; d: OUT std_logic); END ENTITY; ARCHITECTURE ejemplo_arch OF ejemplo IS SIGNAL a,b: std_logic; BEGIN PROCESS(c) VARIABLE z: std_logic; BEGIN a<= c and b; --asignacin de seales: despus de ejecutarse esta lnea a seguir valiendo lo mismo, slo se actualiza al acabar el PROCESS z:= a or c; --asignacin de variables: en el momento de ejecutarse esta lnea z valdr a or c (el valor que tena a cuando empez el PROCESS) END PROCESS; END ARCHITECTURE;

Sentencias secuenciales
IF ... THEN ... ELSE Permite la ejecucin de un bloque de cdigo dependiendo de una o varias condiciones. IF <condicin1> THEN [sentencias 1] ELSIF <condicin2> THEN [sentencias 2] ELSE [sentencias N]

Arquitectura END IF; Un ejemplo es: IF (reloj='1' AND enable='1') THEN salida<=entrada; ELSIF (enable='1') THEN salida<=tmp; ELSE salida<='0'; END IF;

18

CASE Es parecido al anterior porque tambin ejecuta un bloque de cdigo condicionalmente, pero en esta ocasin se evala una expresin en vez de una condicin. Se debe recordar que se deben tener en cuenta todos los casos, es decir, incluir como ltima opcin la sentencia WHEN OTHERS. CASE <expresin> IS WHEN <valor1> => [sentencias1] WHEN <valor2> => [sentencias2] WHEN <rango de valores> => [sentenciasN] WHEN OTHERS => [sentenciasM] END CASE; Un ejemplo es: CASE a IS WHEN 0 WHEN 1 to 50 WHEN 99 to 51 WHEN OTHERS END CASE;

=> => => =>

B:=0; B:=1; B:=2; B:=3;

LOOP LOOP es la forma de hacer bucles en VHDL. Sera el equivalente a un FOR o WHILE de un lenguaje convencional. Su estructura es: [etiqueta:] [WHILE <condicin> | FOR <condicin>] LOOP [sentencias] [exit;] [next;] END LOOP [etiqueta]; Un ejemplo de bucles anidados es:

Arquitectura

19

bucle1: LOOP a:=A+1 b:=20; bucle2: LOOP IF b < (a*b) THEN EXIT bucle2; END IF; b:=b+a; END LOOP bucle2; EXIT bucle1 WHEN a>10; END LOOP bucle1; Otro ejemplo, este con FOR es: bucle1: FOR a IN 1 TO 10 LOOP b:=20; bucle2: LOOP IF b<(a*a) THEN EXIT bucle2; END IF; b:=b-a; END LOOP bucle2; END LOOP bucle1; Otro ms con WHILE cuenta := 10; bucle1: WHILE cuenta >= 0 LOOP cuenta := cuenta + 1; b:=20; bucle2: LOOP IF b<(a*a) THEN EXIT bucle2; END IF; b := b-a; END LOOP bucle2; END LOOP bucle1;

NEXT y EXIT NEXT permite detener la ejecucin actual y seguir con la siguiente. [id_next:] NEXT [id_bucle] [WHEN condicin]; Como se puede suponer, la sentencia EXIT hace que se salga del bucle superior al que se ejecuta. [id_exit:] EXIT [id_bucle] [WHEN condicin];

Arquitectura Se puede ver su uso en los ejemplos del apartado anterior. ASSERT Se usa para verificar una condicin y, en caso de que proceda, dar un aviso. La sintxis es: ASSERT <condicin> [REPORT <expresin>] [SEVERITY <expresin>]; Este comando se estudiar en el subcaptulo de notificaciones, en la seccin de bancos de prueba. Puesto que el uso de este comando se realiza nicamente en la simulacin de circuitos. WAIT La ejecucin de un bloque PROCESS se realiza de forma continuada, como si de un bucle infinito se tratara (se ejecutan todas las sentencias y se vuelven a repetir). Esto no tiene mucho sentido, puesto que continuamente se ejecutara lo mismo una y otra vez, sera interesante poder parar la ejecucin. Una forma de hacerlo e mediante las listas de sensibilidad, las cuales se han visto anteriormente, aunque existe otra forma de hacerlo mediante la sentencia WAIT, pero es algo ms complejo. WAIT ON lista_sensible UNTIL condicion FOR timeout; La lista_sensible es un conjunto de seales separadas por comas. La condicin es una sentencia que activar de nuevo la ejecucin. El timeout es el tiempo durante el cual la ejecucion esta detenida. No es necesario utilizar las tres opciones, en caso de hacerlo la primera condicin que se cumpla volver a activar la ejecucin. WAIT WAIT WAIT WAIT WAIT ON pulso; UNTIL counter = 5; FOR 10 ns; ON pulso, sensor UNTIL counter = 5; ON pulso UNTIL counter = 5 FOR 10 ns;

20

Si se utiliza una lista de sensibilidad no es posible utilizar la sentencia WAIT, sin embargo si es posible utilizar varias sentencias WAIT cuando esta acta como condicin de activacin. Este comando se estudiar en el subcaptulo de retrasos, en la seccin de bancos de prueba.

Descripcin estructural
Las dos descripciones anteriores son las ms utilizadas por los diseadores, ya que son ms cercanos al pensamiento humano. Aunque existe otro tipo de descripcin, que permite la realizacin de diseos jerrquicos. VHDL dispone de diferentes mecanismos para la descripcin estructural.

Definicin de componentes
En VHDL es posible declarar componentes dentro de un diseo mediante la palabra COMPONENT. Un componente se corresponde con una entidad que ha sido declarada en otro mdulo del diseo, o incluso en alguna biblioteca, la declaracin de este elemento se realizar en la parte declarativa de la arquitectura del mdulo que se est desarrollando. La sintxis para declarar un componente es muy parecida a la de una entidad. COMPONENT nombre [IS] [GENERIC(lista_parametros);]

Arquitectura [PORT(lista_de_puertos);] END COMPONENT nombre; Si se dispone de un compilador de VHDL'93 no ser necesario incluir en los diseo la parte declarativa de los componentes, es decir se pasara a referenciarlos de forma directa. Un ejemplo de un componente podra ser el siguiente. COMPONENT mux IS GENERIC( C_AWIDTH : integer; C_DWIDTH : integer ); PORT( control : IN bit; entrada1 : IN bit; entrada2 : IN bit; salida : OUT bit ); END COMPONENT mux;

21

Referencia de componentes
La referencia de componentes consiste en copiar en la arquitectura aquel componente que se quiera utilizar, tantas veces como sea necesario para construir el diseo. Para ello, la sintaxis que presenta la instanciacin de un componente es la siguiente.
ref_id: [COMPONENT] id_componente | ENTITY id_entidad [(id_arquitectura)] | CONFIGURATION id_configuracin [GENERIC MAP (parametros)] [PORT MAP (puertos)];

Un ejemplo de referenciacin del componente anterior sera. mux_1 : mux GENERIC MAP ( C_AWIDTH => C_DWIDTH => ) PORT MAP ( control => entrada1 => entrada2 => salida => );

C_AWIDTH, C_DWIDTH

ctrl, e1, e2, sal

Arquitectura

22

Las seales ctrl, e1, e2 y sal deben ser declaradas previamente en la seccin de declaraciones de la arquitectura, estas seales sirven para poder conectar unos componentes con otros. Tambin deben declararse las variables que se utilizan en la seccin GENERIC.

Organizacin del cdigo


En descripciones de sistemas complejos es necesario una organizacin que permita al diseador trabajar con mayor comodidad. En el captulo anterior se vio como era posible agrupar una serie de sentencias mediante mdulos. Pero existen otras formas de organizar el cdigo, a travs de subprogramas, que harn ms legibles dichos sistemas. Por otro lado, estos subprogramas pueden ser agrupados junto con definiciones de tipos, bloques, ... en estructuras, lo que formaran los denominados paquetes, que a su vez con elementos de configuracin describiran una librera.

Subprogramas
Como en otros lenguajes de programacin, en VHDL es posible estructurar el cdigo mediante el uso de subprogramas. Realmente, un subprograma es una funcin o procedimiento que realiza una determinada tarea, aunque existen ciertas diferencias entre ambas. Una funcin devuelve un valor y un procedimiento devuelve los valores a travs de los parmetros que le han sido pasados como argumentos. Por ello, las primeras debern contener la palabra reservada RETURN, mientras que las segundas no tienen necesidad de disponer dicha sentencia, en caso de tener una sentencia de ese tipo interrumpir la ejecucin del procedimiento. A consecuencia de la anterior, en una funcin todos sus parmetros son de entrada, por lo que slo pueden ser leidos dentro de la misma, por el contrario en un procedimiento los parmetros pueden ser de entrada, de salida o de entrada y salida (unidireccionales o bidireccionales). Las funciones se usan en expresiones, sin embargo, los procedimientos se llaman como una sentencia secuencial o concurrente. Los procedimientos pueden tener efectos colaterales al poder cambiar seales externas que han sido pasadas como parmetros, por otro lado las funciones no poseen estos efectos. Las funciones nunca pueden tener una sentencia WAIT, pero los procedimientos s.

Declaracin de funciones y procedimientos


Las declaraciones de estos elementos pueden realizarse en la parte declarativas de las arquitecturas, bloques, paquetes, etc. A continuacin, se muestra la estructura de un procedimiento. PROCEDURE nombre[(parmetros)] IS [declaraciones] BEGIN [sentencias] END [PROCEDURE] [nombre]; La estructura de las funciones corresponden a las siguientes lneas. [PURE | IMPURE] FUNCTION nombre[(parmetros)] RETURN tipo IS [declaraciones] BEGIN [sentencias] -- Debe incluir un RETURN

Organizacin del cdigo END [FUNCTION] [nombre]; Como ya se explic, la lista de parmetros es opcional en ambos casos. Estos parmetros se declaran de forma similar a como se hacen los puertos de una entidad. <nombre del puerto> : <tipo de puerto> <tipo de objeto> Dependiendo de la estructura que se utilice, funciones o procedimientos, los parmetros tendrn un significado u otro. En las funciones slo es posible utilizar el tipo de puerto IN, mientras que en los procedimientos pueden usarse los tipos IN, OUT e INOUT. Adems, en las funciones el parmetro puede ser CONSTANT o SIGNAL, por defecto es CONSTANT. Por otro lado, en los procedimientos los parmetros de tipo IN son CONSTANT por defecto y VARIABLE para el resto, aunque tambin es posible utilizar SIGNAL siempre que se declare explcitamente. No se aconseja utilizar seales como parmetros, por los efectos que pueden tener en la ejecucin de un programa. Las funciones PURE o puras devuelven el mismo valor para unos parmetros de entrada determinados. Mientras que una funcin es IMPURE o impura si para los mismos valores de entrada se devuelve distinto valor. Estas ltimas pueden depender de una variable o seal global. Realmente, estas palabras reservadas hacen de comentario, puesto que una funcin no se hace impura o pura por indicarlo. Un ejemplo de una funcin sera el siguiente. FUNCTION es_uno(din : std_logic_vector(31 downto 0)) RETURN std_logic IS VARIABLE val : std_logic; BEGIN IF din = X"00000001" THEN val := '1'; ELSE val := '0'; END IF; RETURN val; END es_uno; Por otro lado, un ejemplo de un procedimiento podra pertenecer a las siguientes lneas. PROCEDURE es_uno(din : std_logic_vector(31 downto 0) dout : std_logic) IS BEGIN IF din = X"00000001" THEN dout := '1'; ELSE dout := '0'; END IF; END es_uno;

23

Organizacin del cdigo

24

En la asignacin a la seal de salida se realiza con el operador :=, puesto que no es una seal, es decir que se trata de un tipo VARIABLE. Si se tratara de una seal se hara con el operador de asignacin <=.

Llamadas a subprogramas
Es muy sencillo realizar una invocacin a un subprograma, basta con indicar el nombre de dicho subprograma seguido de los argumentos, los cuales irn entre parntesis. En VHDL existen varias formas de pasar los parmetros a un subprograma. Asociacin implcita: Poniendo los parmetros en el mismo orden en el que se declaran en el subprograma. Por ejemplo, si se dispone del siguiente procedimiento. PROCEDURE limite(CONSTANT conj : IN std_logic_vector(3 DOWNTO 0); VARIABLE min, max : INOUT integer) IS ... limite(cjt(31 DOWNTO 28), valmin, valmax); -- Llamada al procedimiento Asociacin explcita: Los parmetros se colocan en cualquier orden. Un ejemplo de la llamada al procedimiento anterior podra ser la siguiente. limite(min=>valmin, max=>valmax, conj=>cjt(31 DOWNTO 28)); Parmetros libres: En VHDL es posible dejar parmetros por especificar, de forma que tengan unos valores por defecto, y en el caso de pasar un valor a dichos argumentos puedan tomar el valor especificado. Un ejemplo de este tipo de llamadas sera el siguiente. PROCEDURE lee(longuitud : IN integer := 200) IS BEGIN .... END PROCEDURE; -- Posibles llamadas lee; lee(350); Como ya se indic al inicio de este captulo, los subprogramas pueden ser llamados desde un entorno secuencial o concurrente. En caso de ser llamado en un entorno concurrente el procedimiento se ejecutar de forma similar a un bloque PROCESS, por lo que hay que tener alguna sentencia que permita suspender la ejecucin, porque podra ejecutarse de forma continua. Este tipo de sentencias podra ser una lista sensible o una sentencia WAIT, como ya se explic en los bloques PROCESS, como se indic, no es posible utilizar la lista de sensibilidad junto con una sentencia WAIT. Este tipo de sentencias es posible que detengan un procedimiento para siempre si son utilizadas en entornos secuenciales.

Organizacin del cdigo

25

Sobrecarga de operadores
Como en otros lenguajes de programacin, en VHDL tambin es posible sobracargar los mtodos, es decir, tener funciones con el mismo nombre pero con distintos parmetros. Aunque, en este lenguaje hay que tener un poco de cuidado a la hora de declarar los procedimientos, puesto que al ser posible dejar libres algunos argumentos es muy probable encontrar situaciones en las que dos funciones son llamadas de forma idntica cuando se hace sin parmetros. Por ejemplo, si se dispone de los siguientes procedimientos la llamada a stos sin parmetros sera la misma, y no habra forma de diferenciar a qu mtodo se refiere. PROCEDURE lee(longuitud : IN integer := 20) IS BEGIN .... END PROCEDURE; PROCEDURE lee(factor : IN real := 100.0) IS BEGIN .... END PROCEDURE; lee;

Paquetes
Como se coment al principio, un paquete consta de un conjunto de subprogramas, constantes, declaraciones, etc., con la intencin de implementar algn servicio. As se pueden hacer visibles las interfaces de los subprogramas y ocultar su descripcin.

Definicin de paquetes
Los paquetes se separan en dos zonas: declaraciones y cuerpo, aunque esta ltima puede ser eliminada si no se definen funciones y/o procedimientos. Las siguientes lneas muestra la estructura de un paquete. -- Declaracin de paquete PACKAGE nombre IS declaraciones END [PACKAGE] [nombre]; -- Declaracin del cuerpo PACKAGE BODY nombre IS declaraciones subprogramas ... END [PACKAGE BODY] [nombre]; El nombre del paquete debe coincidir en la declaracin del paquete y del cuerpo. A continuacin, se muestra un ejemplo de un paquete.

Organizacin del cdigo

26

-- Declaracin de paquete PACKAGE mi_paquete IS SUBTYPE dir_type IS std_logic_vector(31 DOWNTO 0); SUBTYPE dato_type IS std_logic_vector(15 DOWNTO 0); CONSTANT inicio : dir_type; -- Hay que definirlo en el BODY FUNCTION inttodato(valor : integer) RETURN dato_type; PROCEDURE datotoint(dato : IN dato_type; valor : OUT integer); END mi_paquete; -- Declaracin del cuerpo PACKAGE BODY mi_paquete IS CONSTANT inicio : dir_type := X"FFFF0000"; FUNCTION inttodato(valor : integer) RETURN dato_type IS -- Cuerpo de la funcin END inttodato; PROCEDURE datotoint(dato : IN dato_type; valor : OUT integer) IS -- Cuerpo del procedimiento END datotoint; END PACKAGE BODY mi_paquete; Para acceder a los tipos creados en un paquete, se debe indicar el nombre del paquete seguido del elemento que se desea utilizar, separados por un punto. Para el ejemplo anterior sera algo parecido a las siguientes lneas. VARIABLE dir : work.mi_paquete.dir_type; dir := work.mi_paquete.inicio; Existe otra forma de realizarlo, haciendo visible al paquete de esta forma no se necesitar el punto ni tampoco indicar el nombre del paquete. Para ello, se debe utilizar la sentencia USE seguido del paquete que se va a utilizar y el mtodo a utilizar, todo ello separado por puntos. El ejemplo anterior se podra realizar de la siguiente forma. USE work.mi_paquete.ALL VARIABLE dir : dir_type; dir := inicio;

Libreras
Hasta ahora se han visto varios elementos del lenguaje, como pueden ser las entidades, las arquitecturas, los paquetes, etc. Cuando se realiza una descripcin en VHDL se utilizan estas unidades, en uno o ms ficheros, stos se denominan ficheros de diseo. Posteriormente, estos ficheros sern compilados para obtener una librera o biblioteca de diseo, de forma que esta biblioteca contiene los elementos que componen el circuito. La biblioteca donde se guardan los resultados de la compilacin se denomina work. Una librera se compone de dos partes bien diferenciadas, dependiendo de las unidades que la formen. Por un lado, estn las unidades primarias, que correspondern a entidades, paquetes y archivos de configuracin. Mientras que las unidades secundarias sern arquitecturas y cuerpos de paquetes. Por lo tanto, se puede sacar la conclusin de que

Organizacin del cdigo cada unidad secundaria deber estar asociada con una unidad primaria. Al realizar una compilacin se analizarn las unidades que vayan apareciendo en el texto. Por consiguiente, es importante establecer un orden lgico de las distintas unidades, para que de esta forma se puedan cumplir las dependencias existentes entre las mismas. La forma que toma la librera una vez compilada es muy diversa; dependiendo de la herramienta de compilacin utilizada as ser el resultado obtenido, esto se debe a que en VHDL no existe un estndar para crear bibliotecas. Para incluir una librera a un diseo basta con utilizar la palabra reservada LIBRARY seguida del nombre de la biblioteca a utilizar. Adems, tambin es posible hacer visibles elementos internos de estas bibliotecas con el uso de la sentencia USE, como se explic en el apartado anterior. En el caso de querer hacer visible todos los elementos de un paquete se puede utilizar la palabra reservada ALL. LIBRARY mis_componentes; USE mis_componentes.logic.ALL; En VHDL hay dos libreras que no hacen falta importarlas. Por un lado est la librera work, que contiene las unidades que se estn compilando, y por otro lado, la librera std que contiene los paquetes standard y textio, las cuales contienen definiciones de tipos y funciones para el acceso a ficheros de texto.

27

Librera ieee
Una de las bibliotecas ms utilizadas en el mundo de la industria es la denominada ieee, la cual contiene algunos tipos y funciones que completan a las que vienen por defecto en el propio lenguaje. Dentro de la librera existe un paquete denominado std_logic_1164, con el cual se pueden trabajar con un sistema de nueve niveles lgicos, como puede ser: valor desconocido, alta impedancia, etc. El siguiente cdigo muestra parte de este paquete. PACKAGE std_logic_1164 IS TYPE std_ulogic IS( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '-' );

----------

Indefinido Desconocido 0 1 Alta impedancia Desconocido LOW (weak low o 0 dbil) HIGH (weak high o 1 dbil) Desconocido

TYPE std_ulogic_vector IS ARRAY(NATURAL RANGE <>) OF std_ulogic; FUNCTION resolved(s : std_ulogic_vector) RETURN std_ulogic; SUBTYPE std_logic IS resolved std_ulogic; TYPE std_logic_vector IS ARRAY (NATURAL RANGE <>) OF std_logic;

Otros conceptos

28

Otros conceptos
Hasta este momento se ha ofrecido una visin general del lenguaje VHDL. EN esta seccin se vern algunas cosas que resultan interesantes en algunas ocasiones a la hora de disear algn sistema.

Punteros en VHDL
Algunos lenguajes de programacin permiten reservar espacio de memoria de manera dinmica mediante punteros. Como es sabido, un puntero es una direccin de memoria que apunta a una variable. En VHDL el tipo de datos que permite reservar memoria es a travs de la palabra reservada ACCESS, la forma de de definir un puntero es la siguiente. TYPE tipo_puntero IS ACCESS tipo_elemento; VARIABLE p : tipo_puntero; La variable p corresponde a un puntero que apunta a variables del tipo tipo_elemento. Los punteros slo pueden ser variables, en ningn caso sern seales, por consiguiente solo podrn estar dentro de un proceso (PROCESS). Por otro lado, la creacin de un puntero se realiza mediante la palabra NEW. Un ejemplo para declarar un puntero es el siguiente. TYPE punteroA IS ACCESS integer RANGE 0 TO 255; VARIABLE p : punteroA; .... p := NEW integer RANGE 0 TO 255; p.ALL := 45; Para acceder al contenido de la dreccin apuntada se utiliza la palabra ALL, si no se inicializa el valor que toma, por defecto tomar el valor NULL. Si se desea liberar la memoria utilizada por un puntero se har uso del procedimiento deallocate. Para el caso anterior se realizara de la siguiente forma. Deallocate(p);

Ficheros
En algunas ocasiones es interesante utilizar ficheros para leer informacin o incluso almacenarla. El uso de ficheros nicamente es vlido en la simulacin, mientras que en la sntesis no es posible su uso. Estos ficheros no pueden almacenar matrices multidimensionales, punteros o ficheros.

Abrir y cerrar ficheros


En primer lugar se debe declarar el tipo de datos que contendr dicho archivo. Mediante las palabras reservadas TYPE y FILE se genera la siguiente estructura. TYPE fichero_tipo IS FILE OF tipo; FILE nombre : fichero_tipo IS [modo] "fichero": [fichero_tipo [OPEN modo] IS "fichero"]

-- VHDL'87 -- VHDL'93

Cuando se tratan con ficheros en VHDL, la estructura anterior depende del compilador que se utilice (VHDL'87 y VHDL'93). La primeras lneas son iguales en ambos casos, pero a la hora de indicar el acceso al fichero la sintxis

Otros conceptos difiere de uno a otro compilador. En VHDL'87 el modo puede ser IN (por defecto) si se va a leer y OUT para escribir. Por otro lado, en VHDL'93 el modo es definido mediante un tipo enumerado declarado en la librera correspondiente (file_open_kind), donde se encuentra write_mode, read_mode (por defecto) o append_mode, que indica escritura, lectura y concatenacin respectivamente. A diferencia que en el anterior, en este caso no es necesario abrirlo obligatoriamente en el momento en que se declara. Para posteriormente abrirlo se podra utilizar el siguiente subprograma. PROCEDURE file_open(status: OUT file_open_status; FILE f: file_type; external_name: IN string; open_kind: IN file_open_kind:=read_mode); Al realizar la apertura despus de la declaracin conlleva una flexibilidad mayor, como puede ser la peticin del nombre del fichero. Tambin es posible obtener el estado en el cual se qued el fichero: open_ok, status_error, name_error y mode_error, aunque este parmetro es opcional. Adems de este subprograma existe otro para poder cerrar el fichero abierto. PROCEDURE file_close(FILE f: file_type); A continuacin se muestra un ejemplo de declaracin, apertura y cierre de ficheros. TYPE arch_integer IS FILE OF integer; -- Declaracin y apertura a la vez FILE datos: arch_integer OPEN read_mode IS "input.txt"; -- Declaracin y apertura posterior FILE datos: arch_integer; ..... file_open(datos, "input.txt",read_mode); -- Cerrar file_close(datos);

29

Lectura y escritura de ficheros


Una vez que se ha declarado un fichero es posible realizar diferentes operaciones como son la lectura, la escritura o la propia comprobacin de fin de archivo. Estas operaciones pueden ser realizadas a travs de unos subprogramas que se detallan a continuacin. PROCEDURE read(FILE f: tipo_archivo; value: OUT tipo); PROCEDURE write(FILE f: tipo_archivo; value: IN tipo); PROCEDURE endfile(FILE f: tipo_archivo) RETURN boolean; El siguiente cdigo muestra un ejemplo de como utilizar estos procedimientos. TYPE type_arch IS FILE OF integer; FILE arch : type_arch OPEN read_mode IS "arch.txt"; VARIABLE n : integer; ..... WHILE NOT endfile(arch) LOOP

Otros conceptos read(arch, n); .... END LOOP;

30

Ficheros de texto
Trabajar con ficheros es til, pero hay que recordar que VHDL codifican los datos de forma binaria, lo que implica que es muy poco legible. Por lo tanto, debe haber una manera de traducir los datos de forma que el lenguaje pueda entenderlos, y para el usuario sea fcil de escribir dichos archivos. El paquete textio permite la conversin de tipos.

Bancos de pruebas
En VHDL es posible describir modelos para la simulacin. Estos modelos no tienen demasiadas restricciones, necesitando unicamente un intrprete de las instrucciones VHDL. En cambio, en la sntesis se aaden una cantidad de restricciones como pueden ser aquellas que tienen que ver con las del tiempo, ya que no es posible aplicar retardos a la hora de disear un circuito.

Retrasos
El retraso es uno de los elementos ms importantes de la simulacin, puesto que el comportamiento de un circuito puede cambiar dependiendo del cambio de las diferentes seales. Cuando se realiza una asignacin se produce de forma inmediata, puesto que no se ha especificado ningn retraso. Este comportamiento puede ser alterado mediante la opcin AFTER cuando se asigna un valor a una seal. Su sintaxis corresponde a la siguiente lnea. seal <= valor AFTER tiempo; Donde tiempo es un valor de tiempo indicado en us, ns, ms, ... Un ejemplo puede ser el siguiente. rst <= '0' AFTER 15 ns; Pero esta sentencia es mucho ms compleja, por ejemplo se puede asignar inicialmente un valor y modificarlo posteriormente o incluso que sea modificado cada cierto tiempo. signal clk : std_logic := '0'; .... rst <= '1', '0' AFTER 15 ns; -- Inicialmente rst=1, despues de 15 ns rst=0 clk <= not clk AFTER 5 ns; -- Cada 5 ns clk cambia de valor Tambin es posible introducir una espera entre dos sentencias mediante la palabra reservada WAIT. La sintxis de esta operacin e ms compleja que la anterior. WAIT [ON lista | UNTIL condicion | FOR tiempo]; Lista corresponde a una lista de sensibilidad de seales, es decir, se permanecer en espera hasta que se produzca un cambio en alguna de las seales de la lista. Condicin se trata de una espera indeterminada hasta que la condicin sea verdadera. Por ltimo, el tiempo es un valor definido en una unidad de tiempo. A continuacin se muestra un ejemplo de las tres esperas posibles.

Bancos de pruebas

31

-- WAIT ON stop <= '1'; WAIT ON semaforo; -- Hasta que semaforo no cambie se permanecer en el WAIT stop <= '0';

....

-- WAIT UNTIL ack <= '1'; WAIT UNTIL clk'event and clk = '1'; -- Hasta que no exista un evento de clk y sea uno se permanece en WAIT ack <= '0';

....

-- WAIT FOR start <= '0'; WAIT FOR 50 ns; -- Se espera 50 ns start <= '1';

Niveles lgicos
Normalmente existen tres niveles lgicos: 0, 1 y X, donde ste ltimo se refiere a un valor desconocido (puede estar a alto o bajo nivel, no se sabe cul de los dos). Tambin existen las llamadas fuerzas. S equivale a la salida obtenida de una conexin a alimentacin o a tierra a travs de un transistor. R es idntico al anterior, pero su obtencin es a travs de una resistencia. Z tambin es igual a las anteriores, pero esta vez es cuando la seal es obtenida mediante una alta impedancia. Por ltimo, se encuentra I, que indica que no se sabe qu fuerza existe en el bus. El tipo std_logic ampla estas fuerzas, incluyendo U y -. La primera indica que una seal no ha sido inicializada y la segunda que no importa el valor que se ponga.

Notificaciones
En la simulacin de circuitos es interesante el uso de las notificaciones, gracias a ellas se pueden advertir que seales han sido activadas o incluso comprobar si una seal ha tomado un valor determinado. El uso de notificaciones se realiza mediante ASSERT, seguida de una condicin como elemento de activacin. La sentencia puede utilizarse tanto en entornos concurrentes como en serie. ASSERT <condicin> [REPORT <expresin>] [SEVERITY <expresin>]; Si la condicin no se cumple aparecer en la pantalla del simulador el mensaje que se ha especificado y el nivel de gravedad, ambos son opcionales y en el caso de no indicar ningn mensaje aparecer "Assertion Violation". Los diferentes niveles de gravedad pueden ser (de menor a mayor): note, warning, error (por defecto) y failure. Dependiendo del nivel de gravedad la simulacin puede detenerse. A continuacin se muestran una serie de ejemplos de esta sentencia.

Bancos de pruebas

32

ASSERT adrr = X"00001111"; .... ASSERT addr = X"10101010" REPORT "Direccion Erronea"; .... ASSERT addr > X"00001000" and addr < X"00002000" REPORT "Direccion correcta" SEVERITY note; .... ASSERT addr < X"00001000" and addr > X"00002000" REPORT "Direccion incorrecta" SEVERITY warning;

Descripcin de un banco de pruebas


Una de las partes ms importantes en el diseo de cualquier sistema son las pruebas para la verificacin del funcionamiento de un sistema. Con las metodologas tradicionales la verificacin slo era posible tras su implementacin fsica, lo que se traduca en un alto riesgo y coste adicional. Lo ms sencillo es cambiar las entradas para ver cmo son las salidas, en una herramienta de simulacin, siempre que su diseo sea sencillo, en caso contrario lo ms cmodo sera crear un banco de pruebas. Un banco de pruebas es una entidad sin puertos, cuya estructura contiene un componente que corresponde al circuito que se desea simular y la alteracin de las diferentes seales de entrada a dicho componente, para poder abarcar un mayor nmero de casos de prueba. Es recomendable realizar ls descripcin del banco de pruebas de un sistema a la vez que se describe su diseo. Las siguientes lneas muestra la sintaxis de un banco de pruebas. ENTITY nombre_test IS END nombre_test; ARCHITECTURE test OF nombre_test IS -- Declaraciones BEGIN -- Cuerpo de las pruebas END test; A continuacin se muestran las diferentes metodologas que se pueden llevar a cabo para la realizacin de un banco de pruebas. Para su explicacin se utilizar un ejemplo de un diseo muy sencillo, donde un vector es rotado un bit hacia la izquierda o derecha dependiendo de la entrada met, su entidad corresponde al siguiente trozo de cdigo. ENTITY round IS clk, rst, met : IN std_logic; e : IN std_logic_vector(3 DOWNTO 0); s : OUT std_logic_vector(3 DOWNTO 0) END round;

Mtodo tabular
Para verificar la funcionalidad de un diseo se debe elaborar una tabla con las entradas y las respuestas que se esperan a dichas entradas. Todo ello se deber relacionar mediante cdigo VHDL. Las siguientes lneas muestran un ejemplo con el diseo que se expuso anteriormente. USE work.round; ENTITY test_round IS END test_round;

Bancos de pruebas

33

ARCHITECTURE test OF test_round IS SIGNAL clk, rst, met : std_logic; SIGNAL e, s : std_logic_vector(3 DOWNTO 0); TYPE type_test IS RECORD clk, rst, met : std_logic; e, s : std_logic_vector(3 DOWNTO 0); END RECORD; TYPE lista_test IS ARRAY (0 TO 6) OF type_test; CONSTANT tabla_test : lista_test :=( (clk=>'0', rst =>'1', met=>'0', e=>"0000", s=>"0000"), (clk=>'1', rst =>'0', met=>'0', e=>"0000", s=>"0000"), (clk=>'1', rst =>'0', met=>'0', e=>"0001", s=>"0010"), (clk=>'1', rst =>'0', met=>'0', e=>"1010", s=>"0101"), (clk=>'1', rst =>'0', met=>'1', e=>"0000", s=>"0000"), (clk=>'1', rst =>'0', met=>'1', e=>"0001", s=>"1000"), (clk=>'1', rst =>'0', met=>'1', e=>"1001", s=>"1100")); BEGIN r : ENTITY work.round PORT MAP(clk => clk, rst => rst, met => met, e => e, s => s); PROCESS VARIABLE vector : type_test; VARIABLE errores : boolean := false; BEGIN FOR i IN 0 TO 6 LOOP vector := tabla_test(i); clk<=vector.clk; rst<=vector.rst; met<=vector.met; e<=vector.e; WAIT FOR 20 ns; IF s /= vector.s THEN ASSERT false REPORT "Salida incorrecta" SEVERITY error; errores:=true; END IF; END LOOP; ASSERT errores REPORT "Test OK" SEVERITY note; WAIT; END PROCESS; END test;

Bancos de pruebas

34

Uso de ficheros (vectores de test)


En el caso anterior los casos de prueba y el cdigo de simulacin permanecan juntos, pero es posible separarlos de forma que, por un lado se encuentren las pruebas y por otro el cdigo. Esto es posible ya que VHDL dispone de paquetes de entradas/salida para la lectura/escritura en ficheros de texto, como ya se comento el paquete textio dispone de los subprogramas necesarios para el acceso a dichos ficheros. Supnganse los casos de prueba desarrollados en el caso anterior, en el siguiente fichero de texto se han escrito los vectores de prueba: clk 0 1 1 1 1 1 rst 1 0 0 0 0 0 met 0 0 0 1 1 1 e 0000 0001 1010 0000 0001 1001 s 0000 0010 0101 0000 1000 1100

A continuacin se muestra el cdigo relacionado con la simulacin, en l se incluye el acceso al fichero anterior que contiene los diferentes vectores de test. USE std.textio.ALL; -- No es necesario porque se incluye por defecto USE work.round; ENTITY test_round IS END test_round; ARCHITECTURE test OF test_round IS SIGNAL clk, rst, met : std_logic; SIGNAL e, s : std_logic_vector(3 DOWNTO 0); BEGIN r : ENTITY work.round PORT MAP(clk => clk, rst => rst, met => met, e => e, s => s); PROCESS FILE vector_test : text OPEN read_mode IS "test.txt"; VARIABLE errores : boolean := false; VARIABLE vector : line; VARIABLE clk_tmp, rst_tmp, met_tmp : std_logic; VARIABLE e_tmp, s_tmp : std_logic_vector(3 DOWNTO 0); BEGIN readline(vector_test,vector); -- Lee los nombres (la primera linea) WHILE NOT endfile(vector_test) LOOP readline(vector_test,vector); read(vector,clk_tmp); read(vector,rst_tmp); read(vector,met_tmp); read(vector,e_tmp); read(vector,s_tmp);

Bancos de pruebas clk <= clk_tmp; rst <= rst_tmp; met <= met_tmp; e <= e_tmp; WAIT FOR 20 ns; IF s_tmp /= s THEN ASSERT false REPORT "Salida incorrecta" SEVERITY error; errores:=true; END IF; END LOOP; file_close(vector_test); ASSERT errores REPORT "Test OK" SEVERITY note; WAIT; END PROCESS; END test;

35

Metodologa algortmica
Existe otro tipo de test, los cuales se basan en realizar algoritmos para cubrir el mayor nmero de casos posibles. A continuacin se muestra un ejemplo, el cual aplica esta metodologa.
USE work.round; ENTITY test_round IS END test_round; ARCHITECTURE test OF test_round IS SIGNAL clk : std_logic := '0'; SIGNAL rst, met : std_logic; SIGNAL e, s : std_logic_vector(3 DOWNTO 0); BEGIN clk <= NOT clk after 10 ns; r : ENTITY work.round PORT MAP(clk => clk, rst => rst, met => met, e => e, s => s); PROCESS BEGIN rst <= '1'; met <= '0'; e <= "0000"; WAIT FOR 20 ns; ASSERT (s="0000") REPORT "Error en reset" SEVERITY error; rst <= '0'; e <= "0000"; WAIT FOR 20 ns; ASSERT (s="0000") REPORT "Error desplazamiento izquierda" SEVERITY error; e <= "0001"; WAIT FOR 20 ns; ASSERT (s="0010") REPORT "Error desplazamiento izquierda" SEVERITY error;

Bancos de pruebas

36

e <= "1010"; WAIT FOR 20 ns; ASSERT (s="0101") REPORT "Error desplazamiento izquierda" SEVERITY error; met <= '1'; e <= "0000"; WAIT FOR 20 ns; ASSERT (s="0000") REPORT "Error desplazamiento derecha" SEVERITY error; e <= "0001"; WAIT FOR 20 ns; ASSERT (s="1000") REPORT "Error desplazamiento derecha" SEVERITY error; e <= "1001"; WAIT FOR 20 ns; ASSERT (s="1100") REPORT "Error desplazamiento derecha" SEVERITY error; ASSERT false REPORT "Test Finalizado" SEVERITY note; WAIT; END PROCESS; END test;

Ejemplos

37

Ejemplos
En este captulo se mostrarn ejemplos de diseos lo ms completos posible, van desde la descripcin del problema hasta su simulacin, se deja al lector si dispone del hardware apropiado su sntesis y verificacin real, as como su simulacin mediante el software apropiado. 1. 2. 3. 4. 5. 6. 7. Puerta triestado Multiplexor Sumador Contador Biestable-Latch Mquinas de estados ALU

Puerta triestado
El objetivo es crear una puerta que tenga una seal de operacin la cual, a estado alto, habilite la salida, por lo tanto el valor de la entrada pasar a la salida. Cuando la seal de operacin est a nivel bajo la puerta no sacar una seal, es decir, estar en alta impedancia. Entradas: entrada: entrada de datos. op: seal que indica el modo de funcionar de la puerta. Salidas: salida: salida de datos. LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; ENTITY triestado IS PORT(op, entrada: IN std_logic; salida: OUT std_logic); END triestado; ARCHITECTURE synth OF triestado IS BEGIN PROCESS(entrada,op) BEGIN IF op='1' THEN salida <= entrada; ELSE salida <= 'Z'; END IF; END PROCESS; END ARCHITECTURE synth;

Puerta triestado

38

Multiplexor
El objetivo es crear un sistema que devuelva un valor dependiente de otra seal de entrada, la cual ser la encargada de seleccionar la salida. Adems se definirn varias entradas de datos que actuarn como salidas. Cuando la seal de seleccin este a cero no se producir ninguna salida, es decir el valor ser cero. Entradas: a, b, c: entradas de datos. sel: seal que indica la seal que va a ser devuelta. Salidas: salida: salida de datos. library IEEE; use IEEE.STD_LOGIC_1164.all; ENTITY mux IS PORT(a b c sel salida END mux;

: : : : :

IN std_logic_vector(3 DOWNTO 0); IN std_logic_vector(3 DOWNTO 0); IN std_logic_vector(3 DOWNTO 0); IN std_logic_vector(1 DOWNTO 0); OUT std_logic_vector(3 DOWNTO 0));

ARCHITECTURE synth OF mux IS BEGIN PROCESS (sel, a, b, c) IS BEGIN CASE sel IS WHEN "00" => salida <= (others => '0'); WHEN "01" => salida <= a; WHEN "10" => salida <= b; WHEN "11" => salida <= c; WHEN OTHERS => salida <= (others => '0'); END CASE; END PROCESS; END synth;

Sumador

39

Sumador
El objetivo es crear un sumador que dadas dos entradas de datos devuelva la suma de estos. Entradas: a: operando 1. b: operando 2. Salidas: salida: suma de las entradas. library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; ENTITY sum IS PORT (a : IN std_logic_vector(3 DOWNTO 0); b : IN std_logic_vector(3 DOWNTO 0); salida : OUT std_logic_vector(4 DOWNTO 0)); END sum; ARCHITECTURE synth OF sum IS BEGIN PROCESS (a, b) IS BEGIN salida <= std_logic_vector(UNSIGNED(a) + UNSIGNED(b)); END PROCESS; END synth;

Contador

40

Contador
El objetivo es crear un contador con reset asncrono, seal de habilitacin y salida con un nmero de bits configurable, con la siguiente definicin de interfaz: Entradas: reset: Reset del sistema. clk: Reloj del sistema. enable: Activacin-Desactivacin del contador. Salidas: count: Salida del contador. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all; ENTITY count IS GENERIC (width:POSITIVE:=8); PORT (clk : IN std_logic; reset : IN std_logic; enable: IN std_logic; count : OUT std_logic_vector(width-1 DOWNTO 0) ); END count; ARCHITECTURE arch1 OF count IS SIGNAL cnt : UNSIGNED(width-1 DOWNTO 0); BEGIN pSeq : PROCESS (clk, reset) IS BEGIN IF reset = '1' THEN cnt <= (others => '0'); ELSIF clk'event AND clk='1' THEN IF enable='1' THEN cnt <= cnt + 1; END IF; END IF; END PROCESS; count <= std_logic_vector(cnt); END arch1;

Contador

41

Biestable-Latch
El objetivo es crear un dispositivo capaz de reproducir en cada tic de reloj la entrada en la salida. Para ello ser necesario diponer del reloj y reset del sistema. Entradas: rst: Reset del sistema. clk: Reloj del sistema. a: Entrada de datos. Salidas: b: Salida de datos. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; ENTITY biestable IS PORT (clk : IN std_logic; rst : IN std_logic; a : IN std_logic_vector(31 DOWNTO 0); b: OUT std_logic_vector(31 DOWNTO 0)); END biestable; ARCHITECTURE synth OF biestable IS BEGIN pSeq : PROCESS (clk, rst) IS BEGIN IF rst = '1' THEN b <= (others => '0'); ELSIF clk='1' AND clk'event THEN b <= a; END IF; END PROCESS; END synth; Tambin es posible realizar esta operacin a travs de una seal de activacion (enable), pero a este tipo de diseos se les denomina latch. En este caso no har falta la seal de reloj, pero s el reset. Entradas: rst: Reset del sistema. en: Enable de almacenamiento. a: Entrada de datos. Salidas: b: Salida de datos.

Biestable-Latch

42

LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; ENTITY latch IS PORT (en : IN std_logic; rst : IN std_logic; a : IN std_logic_vector(31 DOWNTO 0); b: OUT std_logic_vector(31 DOWNTO 0)); END latch; ARCHITECTURE synth OF latch IS BEGIN pSeq : PROCESS (en, rst) IS BEGIN IF rst = '1' THEN b <= (others => '0'); ELSIF en = '1' THEN b <= a; END IF; END PROCESS; END synth;

Mquinas de estados

43

Mquinas de estados
El objetivo es crear un sistema que genere unas salidas determinadas, dependiendo de los estados por donde va fluyendo la ruta de datos. Por consiguiente, har falta el reset y reloj del sistema como entradas del sistema. Tambin se aade una seal para sacar el estado al exterior. Entradas: rst: Reset del sistema. clk: Reloj del sistema. Salidas: a: Salida de datos. b: Salida de datos. estado: Salida del estado. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY maquina_estados IS PORT (clk : IN std_logic; rst : IN std_logic; a : OUT std_logic; b : OUT std_logic; estado : OUT std_logic_vector(3 downto 0)); END maquina_estados; ARCHITECTURE synth OF maquina_estados IS SIGNAL pstate, n_state : std_logic_vector(3 downto 0); BEGIN -- maquina de estados PROCESS (clk, rst) BEGIN IF rst = '1' THEN pstate <= "0000"; ELSIF clk = '1' AND clk'event THEN pstate <= n_state; END IF; END PROCESS; estado <= pstate; n_state <= "0001" WHEN (pstate "0010" WHEN (pstate = "0011" WHEN (pstate "0100" WHEN (pstate = "0101" WHEN (pstate = "0000") ELSE "0001") ELSE = "0010") ELSE "0011") ELSE = "0100") ELSE

Mquinas de estados "0011" WHEN "0111" WHEN "1000" WHEN "1001" WHEN "0000"; a <= '1' WHEN pstate '0' WHEN pstate = '0' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '0'; b <= '1' WHEN pstate '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '0' WHEN pstate = '0' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '1' WHEN pstate = '0'; END synth; (pstate (pstate (pstate (pstate = = = = "0101") "0011") "0111") "1000") ELSE ELSE ELSE ELSE

44

= "0000" ELSE --0 "0001" ELSE --1 "0010" ELSE --2 "0011" ELSE --3 "0100" ELSE --4 "0101" ELSE --5 "0110" ELSE --6 "0111" ELSE --7 "1000" ELSE --8 "1001" ELSE --9

= "0000" ELSE --0 "0001" ELSE --1 "0010" ELSE --2 "0011" ELSE --3 "0100" ELSE --4 "0101" ELSE --5 "0110" ELSE --6 "0111" ELSE --7 "1000" ELSE --8 "1001" ELSE --9

ALU

45

ALU
El objetivo es crear un dispositivo capaz de realizar cualquier operacin dependiendo del valor de una seal de entrada, adems se dispondr de dos entradas de datos. Entradas: a: Entrada de datos 1. b: Entrada de datos 2. proceso: Entrada de la operacin. Salidas: c: Salida de datos. LIBRARY ieee; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all ENTITY alu IS PORT(op1 : IN std_logic_vector(7 DOWNTO 0);--entrada 1 op2 : IN std_logic_vector(7 DOWNTO 0);--entrada 2 proceso : IN std_logic_vector(3 DOWNTO 0);--que hara la alu res : OUT std_logic_vector(15 DOWNTO 0)); END alu; ARCHITECTURE synth OF alu IS SIGNAL a,b:UNSIGNED(op1'range); SIGNAL c:UNSIGNED(res'range); BEGIN PROCESS (a, b, proceso) BEGIN CASE proceso IS WHEN "0000" => c <= RESIZE((a + b),c'length); WHEN "0001" => c <= RESIZE((a - b),c'length); WHEN "0010" => ........ WHEN OTHERS => null; END CASE; END PROCESS; a <= UNSIGNED(op1); b <= UNSIGNED(op2); res <= std_logic_vector(c); END synth;

ALU

46

Apndices
1. Sntesis 2. Instalacin y uso de GHDL

Sntesis
La sntesis de un circuito consiste en abstraer la descripcin del circuito hasta conseguir un diseo puramente estructural. Cualquier descripcin VHDL es sintetizable, independiente del nivel de abstraccin, evidentemente no ser el diseo ms apropiado puesto que la velocidad que se requiere no se cumplir, pero su funcionalidad si corresponder a lo descrito. Hoy en da las herramientas de sntesis realizan la sntesis de forma eficiente, pero an no se encuentran tan avanzadas para realizar la sntesis a partr de una descripcin de alto nivel, puesto que la optimizacin es psima.

Restricciones y Consejos
En esta seccin se ver como interpreta algunas instrucciones en VHDL las herramientas de sntesis. Muchas herramientas de sntesis realizan mal la sntesis de ciertas partes, por consiguiente el diseador debe facilitar estas partes. Es posible que el comportamiento que se obtiene en la simulacin sea la misma que en la sntesis, puesto que en un circuito real existen retrasos o incluso el comportamiento puede variar. Adems dependiendo de la herramienta de sntesis utilizada se obtedrn unos resultados u otros. Evitar clusulas temporales y esperas. El uso de retrasos esta prohibido, puesto que el propio sintetizador ignorar estos retrasos. Al igual que las esperas mediante el comando WAIT (no las listas de sensibilidad mediante dicha palabra). Identificadores de puertas claros. Uso de funciones y mdulos. La divisin del cdigo ayuda a la sntesis del cdigo. Adems de la posible reutilizacin. Cuidado con las listas sensibles. Incluir las seales pertinentes para poder activar el proceso oportuno. Permitir discrepancia. Es posible asignaciones dl tipo s <= NOT s. Inicializacin de variables y seales. Normalmente la sntesis no toma en cuenta ninguna inicializacin, a menos que se disponga de un reset o algo parecido. Seales de reloj. Slo se permite una seal de reloj por proceso, indicndola de la siguiente manera: clk='1' and clk'event. Asignaciones nicas. Niveles lgicos. No se admiten todos los valores de una seal, como puede ser el don't care. Evitar IF's anidados. Como mximo tres niveles, pero lo mejor es utilizar bloques CASE.

Sntesis

47

Construcciones bsicas
Existen dos formas de describir la lgica de un diseo, stas son combinacional o secuencial.

Descripcin de la lgica combinacional


Si la salida del circuito depende de una o varias entradas en ese mismo instante, es decir que lo sucedido anteriormente no afecta a la salida, se podr describir como lgica combinacional. Una seal la cual se le est asignando un valor no debe intervenir en dicha asignacin en caso de la ejecucin concurrente. Ejemplo: -- Combinacional a <= b WHEN t = '1' ELSE c; d <= b AND a; -- Secuencial a <= b WHEN t = '1' ELSE a; d <= b AND d; En caso de la ejecucin serie debe asegurarse que las seales de activacin de un proceso se encuentran en la lista de sensibilidad. Tambin se deben contemplar todos los casos posibles cuando existen instrucciones condicionales, en caso de que no se contemple alguna condiccin se tratara de un latch, por lo tanto se trata de un elemento de memoria. Ejemplo: -- Combinacional PROCESS (b,c,d,e) BEGIN IF b = '1' THEN d <= c; ELSE d <= '0'; END IF; a <= d OR e; END PROCESS; -- Secuencial PROCESS (b,c,d,e) BEGIN IF b = '1' THEN d <= c; END IF; a <= d OR e; END PROCESS;

Sntesis

48

Descripcin de la lgica secuencial


Si la salida del diseo implementado depende de la entrada actual y del estado anterior o de las entradas que sucedieron, se deber realizar una descripcin secuencial. Descripcin de cerrojos. Un cerrojo mantiene la salida a un valor cuando una seal de entrada la activa. Es posible realizarlo de forma concurrente y serie. Serie: Existen varias opciones. No se consideran todas las opciones. PROCESS (b,en) BEGIN IF en = '1' THEN a <= b; END IF; END PROCESS; No se especifican todas las seales en la lista de sensibilidad. La mayora de los sintetizadores incluyen todas las seales que intervienen en el proceso de aignacin o consulta. PROCESS (b) BEGIN a <= c OR b; END PROCESS; Concurrente: Cuando una seal interviene en la asignacin de s misma. a <= b AND c WHEN t = '1' ELSE a; Descripcin de seales de reloj. Una seal de reloj se obtiene en el instante de un flanco de subida o bajada de una seal, en VHDL slo es posible una de ambas formas, es decir o mediante la subida o la bajada, pero no ambas. nicamente es posible un nico reloj por proceso, y a la hora de detectar dicho evento no debe haber un ELSE, ni tampoco negar el evento con un NOT. clk = '0' AND clk'event clk = '1' AND clk'event Cabe resaltar que existen expresiones equivalentes para estas descripciones de seales de reloj. -- clk = '0' AND clk'event falling_edge(clk) -- clk = '1' AND clk'event rising_edge(clk)

Sntesis

49

Decripcin de registros. Son como latches, pero la salida se activa en uno de los flancos. PROCESS (clk, rst) BEGIN IF rst = '1' THEN a <= '0' ELSIF clk = '1' AND clk'event THEN a <= b; END IF; END PROCESS;

Mquinas de estados
Lo ms comn a la hora de disear un circuito, es realizar su descripcin mediante una mquina de estados. Una maquina de estados se compone de do partes, una que calcula el siguiente estado dependiendo de las entradas y del estado actual, y otra que calcula la salida. Existen do tipos de mquinas de estados, una las de Mealy, que son muy generales y su salida depende del estado actual y las entradas, y la otra las de Moore, que son un subconjunto de las anteriores, ya que la salida slo depende del estado actual. A continuacin se muestra la elaboracin de una mquina de estados sncrona. ENTITY maq_est IS PORT ( clk : rst : a : b : c :

IN IN IN IN OUT

std_logic; std_logic; std_logic_vector(3 downto 0); std_logic; std_logic_vector(3 downto 0));

END maq_est; ARCHITECTURE syn OF maq_est IS TYPE Type_state IS (stIDLE, stWAIT, stOPER); SIGNAL state, next_state : Type_state; BEGIN -- syn pSeq: PROCESS (clk, rst) BEGIN -- process pSeq IF rst = '1' THEN state <= stIDLE; ELSIF clk'event AND clk = '1' THEN state <= next_state; END IF; END PROCESS pSeq; pCom: PROCESS (state, a, b)

Sntesis BEGIN -- process pCom next_state <= state; c <= (OTHERS => '0'); CASE state IS WHEN stIDLE => IF b = '1' AND a = "1111" THEN next_state <= stOPER; ELSIF b = '1' THEN next_state <= stWAIT; END IF; WHEN stWAIT => IF a = "1111" THEN next_state <= stOPER; END IF; WHEN stOPER => c <= "1010"; IF b = '0' THEN next_state <= stIDLE; END IF; WHEN OTHERS => null; END CASE; END PROCESS pCom; END syn;

50

Lgica programable
Qu es un PLD (Dispositivo de Lgica Programable) Un dispositivo lgico programable es un circuito integrado, formado por una matriz de puertas lgicas y flip-flops, que proporcionan una solucion al diseo de forma anlogas, a las soluciones de suma de productos, productos de sumas y multiplexores. La estructura bsica de una PLD permite realizar cualquier tipo de circuito conbinacional basndose en una matriz formada por puertas AND, seguida de una matriz de puertas OR. Tres son los tipos ms estendidos de PLD's, la PROM, PLA, y la PAL. PROM (Programmable Read Only Memory): Este tipo de dispositivo se basa en la utilizacin de una matriz AND fija, seguida de una matriz OR programable. La matriz programable esta formada por lneas distribuidas en filas y columnas en las cuales los puntos de cruce quedaran fijos por unos diodos en serie con unos fusibles que sern los encargados de aislar las uniones donde no se requiera la funcion lgica. La fase de programacin se realiza haciendo circular una corriente capaz de fundir el fusible en aquellas uniones donde no se desee continuidad. Por otra parte, para cada combinacion de las seales de entrada, el codificador activa una nica fila y a su vez activa aquella columna a las que esta todava unida a travz del diodo. PLA (Programmable Logic Array): Parecido en la dispositivo a la PROM, difiere de esta, en que aqu en la PLD , ambas matrices, la de puertas And, as como la de puertas Or es programable, por lo que nos vemos habilitados a

Sntesis incrementar el nmero de entradas disponibles, sin aumentar el tamao de la matriz. Esta estructura permite una mejor utilizacin de los recursos disponibles en el circuito integrado, de tal forma que se genera el mnimo numero de trminos necesarios para generar una funcin lgica . PAL (Programmable array Logic): Una PAL es diferente de una PROM a causa de que tiene una red Y programable y una red O fija. Con un programador Prom podemos obtener los productos fundamentales deseados quemando los eslabones y luego conseguir la suma lgica de dichos productos mediante las conexiones fijas de salida. FPGA (Field Programmable Gate Array): Una FPGA es la ultima tecnologia de dispositivos programables. Se puede reprogramar y las ultimas veriones lo permiten de forma dinamica. Implementan modulos programables, memorias, flip-flops e interconexiones. Lo que permite la mayor flexibilidad en este tipo de despositivos. Se suele utilizar para equipos que se puedan reprogramar y como dispositivos para realizar los TEST de equipos que parasar a fabricarse en ASICs.

51

Instalacin y uso de GHDL


GHDL es un programa para Linux y Windows con licencia GPL que puede compilar y simular ficheros en VHDL. GHDL es un compilador basado en la tecnologa de GCC y que genera ejecutables. Tambin se usar el programa GTKWave para visualizar los resultados de la simulacin. Se ha elegido este programa para compilar y simular los programas de este libro por ser libre y gratuito. No obstante hay muchos otros programas, tambin para Windows, que pueden ser usados, algunos son: ActiveVHDL (Altec) Leapfrog (Cadence) Leonardo (Mentor Graphics) Max Plus II (Altera) Project Manager y Modelsim (Xilinx) SYNOPSYS VeryBest

Instalacin
El compilador GHDL puede descargarse de http:/ / ghdl. free. fr/ en sus versiones de Windows, Linux y cdigo fuente Ada. Si se opta por la tercera opcin se necesita instalar el compilador GNAT (ver instalacin de GNAT en el wikilibro de Ada). Los programas normalmente llevan un fichero que explica la forma de instalarlos. Tambin puede consultarse en espaol en la pgina http://dl.dropbox.com/u/38510482/comidilla/ghdl.html.

Instalacin y uso de GHDL

52

Compilar y simular con GHDL


Para compilar un programa hay que abrir la consola e ir al directorio donde estn los ficheros creados. En primer lugar hay que compilar los ficheros del diseo y despus los bancos de pruebas. Para compilar hay que usar el programa ghdl: En este ejemplo se simular un simple negador de una entrada y una salida. El fichero se llama negador.vhd y el cdigo es: ENTITY negador IS PORT (a: IN bit; b: OUT bit); END negador; ARCHITECTURE neg OF negador IS BEGIN b < =not a; END neg; El banco de pruebas es un fichero llamado negador_tb.vhd que contiene el siguiente cdigo: ENTITY negador_tb IS END negador_tb; ARCHITECTURE neg_tb OF negador_tb IS COMPONENT negador PORT (a: IN bit; b: OUT bit ); END COMPONENT; SIGNAL a: bit; SIGNAL b: bit; BEGIN u0: negador PORT MAP (a,b); a <= '1' after 0 ns,'0' after 5 ns,'1' after 10 ns, '0' after 15 ns; END neg_tb; Una vez que se tienen los ficheros se escribe en la consola: ghdl -a ghdl -a ghdl -e ghdl -r gtkwave negador.vhd negador_tb.vhd negador_tb negador_tb --vcd=negador.vcd negador.vcd

A continuacin se pueden ver unas capturas de pantalla de los comandos y del resultado: En GTKWave hay que seleccionar qu seales se quieren visualizar y cunto tiempo se muestra. En la siguiente imagen se ha presionado el botn "Show All" y se han dejado nicamente las seales a y b. Para ms informacin sobre estos programas consultar sus respectivas ayudas.

Bibliografa

53

Bibliografa
Recursos en internet
GHDL [1] IEEE [2] Open Cores [3] VHDL [4] XESS [5]

Libros y otros textos


VHDL Programming by Example, Douglas L. Perry (McGraw-Hill). VHDL Lenguaje para descripcin y modelado de circuitos, Fernando Pardo Carpio (Universidad de Valencia, Espaa). The VHDL Cookbook, Peter J. Ashenden (Universidad de Adelaida, Australia). Diseo de circuitos digitales con VHDL [6], F. Machado, S. Borromeo (Archivo Abierto de la Universidad Rey Juan Carlos) Diseo de sistemas digitales con VHDL [7], F. Machado, S. Borromeo, C. Rodrguez (Archivo Abierto de la Universidad Rey Juan Carlos)

Referencias
[1] [2] [3] [4] [5] [6] [7] http:/ / ghdl. free. fr/ http:/ / www. ieee. org/ http:/ / www. opencores. org http:/ / www. vhdl. org/ http:/ / www. xess. com/ http:/ / hdl. handle. net/ 10115/ 4045 http:/ / hdl. handle. net/ 10115/ 5700

Fuentes y contribuyentes del artculo

54

Fuentes y contribuyentes del artculo


Programacin en VHDL Fuente: http://es.wikibooks.org/w/index.php?oldid=191988 Contribuyentes: Julian.caba, ManuelGR, MarcoAurelio, Oleinad, Rafa, 5 ediciones annimas Introduccin Fuente: http://es.wikibooks.org/w/index.php?oldid=180346 Contribuyentes: Jarisleif, Julian.caba, ManuelGR, MarcoAurelio, Rafa, 12 ediciones annimas Elementos bsicos del lenguaje Fuente: http://es.wikibooks.org/w/index.php?oldid=192443 Contribuyentes: Julian.caba, Rafa, Swazmo, 11 ediciones annimas Entidad Fuente: http://es.wikibooks.org/w/index.php?oldid=155254 Contribuyentes: Julian.caba, MarcoAurelio, Rafa, 8 ediciones annimas Arquitectura Fuente: http://es.wikibooks.org/w/index.php?oldid=195576 Contribuyentes: Julian.caba, Kranfix, MarcoAurelio, Rafa, 11 ediciones annimas Organizacin del cdigo Fuente: http://es.wikibooks.org/w/index.php?oldid=195564 Contribuyentes: Julian.caba, 5 ediciones annimas Otros conceptos Fuente: http://es.wikibooks.org/w/index.php?oldid=135216 Contribuyentes: Julian.caba, 3 ediciones annimas Bancos de pruebas Fuente: http://es.wikibooks.org/w/index.php?oldid=172131 Contribuyentes: Der Knstler, Julian.caba, MarcoAurelio, 10 ediciones annimas Ejemplos Fuente: http://es.wikibooks.org/w/index.php?oldid=137121 Contribuyentes: Julian.caba, MarcoAurelio, Rafa Puerta triestado Fuente: http://es.wikibooks.org/w/index.php?oldid=153028 Contribuyentes: Julian.caba, Karj, MFriginal, ManuelGR, MarcoAurelio, Rafa Multiplexor Fuente: http://es.wikibooks.org/w/index.php?oldid=195146 Contribuyentes: Felip.m11, Julian.caba, ManuelGR, MarcoAurelio, 6 ediciones annimas Sumador Fuente: http://es.wikibooks.org/w/index.php?oldid=178620 Contribuyentes: Julian.caba, ManuelGR, MarcoAurelio, 5 ediciones annimas Contador Fuente: http://es.wikibooks.org/w/index.php?oldid=178619 Contribuyentes: Julian.caba, ManuelGR, MarcoAurelio, 6 ediciones annimas Biestable-Latch Fuente: http://es.wikibooks.org/w/index.php?oldid=137122 Contribuyentes: Julian.caba Mquinas de estados Fuente: http://es.wikibooks.org/w/index.php?oldid=178621 Contribuyentes: Julian.caba, MarcoAurelio, 2 ediciones annimas ALU Fuente: http://es.wikibooks.org/w/index.php?oldid=178623 Contribuyentes: Julian.caba, ManuelGR, MarcoAurelio, 3 ediciones annimas Apndices Fuente: http://es.wikibooks.org/w/index.php?oldid=171398 Contribuyentes: Julian.caba, Magister Mathematicae, ManuelGR, MarcoAurelio, Rafa Sntesis Fuente: http://es.wikibooks.org/w/index.php?oldid=195574 Contribuyentes: Julian.caba, Kranfix, MarcoAurelio, 7 ediciones annimas Instalacin y uso de GHDL Fuente: http://es.wikibooks.org/w/index.php?oldid=174302 Contribuyentes: Jarisleif, Julian.caba, ManuelGR, Rafa, 6 ediciones annimas Bibliografa Fuente: http://es.wikibooks.org/w/index.php?oldid=195145 Contribuyentes: Felip.m11, Julian.caba, ManuelGR, MarcoAurelio, Rafa

Fuentes de imagen, Licencias y contribuyentes

55

Fuentes de imagen, Licencias y contribuyentes


Archivo:100%.svg Fuente: http://es.wikibooks.org/w/index.php?title=Archivo:100%.svg Licencia: Public Domain Contribuyentes: Siebrand Archivo:75%.svg Fuente: http://es.wikibooks.org/w/index.php?title=Archivo:75%.svg Licencia: Public Domain Contribuyentes: Siebrand

Licencia

56

Licencia
Creative Commons Attribution-Share Alike 3.0 Unported //creativecommons.org/licenses/by-sa/3.0/

You might also like