V. Elementos de VHDL F. Santiago E. 1 Tipos de Datos Todos los sistemas digitales manejan la información como bits o vectores de bits. Sin embargo, no es posible ni conveniente usar sólo estos tipos para todos los datos. Por ejemplo, para una memoria: RAM Convendría usar un arreglo de Bytes Convendría usar números Decimales o Hexadecimales Decodificador de direcciones 1k x 8 Arreglo de bits Control Tiempo de Acceso 10 nS Los tipos bit y bit_vector no se ajustan, el tipo aplicable es Time (que es un tipo físico) Por lo tanto, VHDL debe incluir otros tipos de datos. F. Santiago E. 2 Tipos Escalares Booleano : Declarado como: type BOOLEAN is (false, true); Descripción: Los valores Booleanos son TRUE/FALSE que no necesariamente son iguales a 0/1. Es decir , TRUE no es lo mismo que ‘1’ y viceversa. Bit y Boolean son dos tipos diferentes. Ejemplos: True, false Caracter : Declarado como: type CHARACTER is (null, . . ., ‘a’, ‘b’, ‘c’, . . . ); Descripción: Cubre todos los caracteres definidos en el conjunto que establece la definición ISO 8859-1 (Conocida también como Latín – 1). Ejemplos: ‘0’, ‘*’, ‘¿’, ‘A’, ‘}’ F. Santiago E. 3 Entero : Declarado como: type INTEGER is range –2147483648 to 2147483647; Descripción: Un entero requiere de 32 bits, sin embargo, la mayoría de aplicaciones utilizan enteros con rangos menores. Con la siguiente declaración: subtype ENTERO_CORTO is integer range 0 to 7; Se declara un subtipo de entero que ocupa sólo 3 bits, luego pueden declararse señales o variables: signal A: ENTERO_CORTO; variable X: ENTERO_CORTO; Si solo se va a usar una señal, la definición e instanciación pueden hacerse en una solo expresión, por ejemplo: signal ENT_CORTO2: INTEGER range 0 to 31; Ejemplos: 12, 0, 2147483646, -100, 16 F. Santiago E. 4 Real : Declarado como: type REAL is range –1.0 E308 to 1.0 E308; Descripción: También es conocido como Punto flotante, por lo general se maneja un sub-rango que depende de la aplicación. Ejemplos: 0.0, 1.000001, -1.0 e5 Nota: La representación de los números reales es compleja, de manera que no se puede sintetizar directamente. Bit : Declarado como: type BIT is (‘0’, ‘1’); Descripción: El tipo Bit es una enumeración que define dos valores lógicos estándares: ‘0’ y ‘1’. Es el único que puede usarse para operaciones lógicas. Ejemplos: ‘0’, ‘1’ F. Santiago E. 5 Enumeraciones: Tipos definidos por el usuario. Están disponibles para que el diseñador pueda contar con información personalizada, para un mayor entendimiento. Una aplicación clásica de los Tipos Definidos por el Usuario se presenta en una Máquina de Estados Finitos (FSM), para representar un diseño secuencial, a cada estado se le asigna un nombre. IDLE EXECUTE FETCH DECODE type EstadosFSM is (IDLE, FETCH, DECODE, EXECUTE); signal Edo_Act, Edo_Ant: EstadosFSM; Durante la síntesis, los estados se codifican con bits que serán manejados con flipflops. F. Santiago E. 6 Tipos Fisicos Los tipos físicos son únicos en VHDL, ya que no sólo especifican los valores de los objetos sino también sus unidades. El estándar de VHDL sólo incluye un tipo físico: El tiempo (Time), pero otros tipos pueden también definirse. Type time is range –2147483647 to 2147483647 units fs; -- Primarias ps = 1000 fs; -- Secundarias ns = 1000 ps; us = 1000 ns; ms = 1000 us; sec = 1000 ms; Nota: El tipo físico time sólo es utilizado para simulación, no puede ser sintetizado. min = 60 sec; hor = 60 min; end units; F. Santiago E. 7 Tipos Complejos Arreglos: Son tipos complejos con una estructura regular que contiene elementos del mismo tipo. El número de elementos está especificado en el rango del arreglo. El rango puede ser ilimitado: range < > (aunque no es lo más conveniente). Hay dos arreglos pre-definidos en VHDL : • Bit_Vector – Con elementos del tipo Bit, y • String – Con elementos de tipo carácter. Si estos arreglos se declaran con rango ilimitado, difieren en su limite inferior por default en el bit_vector es 0 y en un string es 1. F. Santiago E. 8 Arreglos . . . Ejemplo: Signal DataBus : bit_vector ( 7 downto 0 ); 7 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 MSB LSB Único elemento (comilla simple): DataBus( 7 ) = ‘0’; DataBus( 3 ) = ‘1’; Dos o mas elementos (comilla doble): DataBus = “01001101”; DataBus( 5 downto 3) = “001”; Los vectores de bits se puede escribir en binario, octal, decimal y hexadecimal. “01111” O “17” X “F” binario octal hexadecimal F. Santiago E. 9 Arreglos . . . Puesto que los arreglos sólo tienen una dimensión, también son conocidos como vectores. El usuario puede declarar arreglos con dimensiones mayores, aunque tres o mas son poco tratables. Memoria de 1 K x 4 Un ejemplo típico es una memoria: 0 Type memory1k4 is Array ( 0 to 1023 ) of Bit_Vector ( 3 downto 0 ); 1 2 3 Signal Memory : memory1k4; 1019 1020 Es una especie de Vector de Vectores. 1021 1022 1023 F. Santiago E. 10 Registros (records) También son tipos complejos, difieren de los arreglos en que sus elementos pueden ser de diferentes tipos y son referenciados por su nombre y no por un índice. Ejemplo : Type Instr_T mnemonico opcode CiclosEx End record; Signal is : : : record String ( 1 to 14 ); Bit_Vector ( 3 downto 0 ); Integer; Instr1, Instr2, Instr3 : Instr_T; Instr1.mnemonico = “add reg1 reg2”; Instr1.opcode = “0010”; Instr1.CiclosEx = 2; Instr2.mnemonico = “xor reg1 reg2”; Instr2.opcode = “0001”; Instr2.CiclosEx = 1; Nota : No todos los records son sintetizables, pero la mayoría de herramientas que sintetizan cubren los records que incluyen los tipos: bit, bit_vector, boolean e integer. Instr3.mnemonico = “mul reg1 reg2”; Instr3.opcode = “1110”; Instr3.CiclosEx = 8; F. Santiago E. 11 Operadores y Expresiones Aparte de los sistemas triviales, las señales de entrada deben ser transformadas de alguna forma para generar las señales de salida deseadas. Outputs <- transformaciones( inputs ) Las transformaciones son realizadas por expresiones : Fórmulas que consisten de operadores con un apropiado número de operandos. La especificación del comportamiento de un sistema puede ser vista como un conjunto ordenado de expresiones aplicadas sobre las señales de entrada. Operadores Lógicos: AND, OR, NAND, NOR, XOR y XNOR ( binarios ) NOT ( unario ) Aplicables en los tipos: Bit, Booleano y Bit_Vector (Ambos operandos deben ser del mismo tipo). F. Santiago E. 12 Operadores Numéricos: OPERADOR SIMBOLO EJEMPLOS DE USO Suma + IntX1 + 17, RealX2 + 2.0 Resta - BusWidth – 1 Producto * A * B (ambos enteros o ambos reales), Mult * 5nS (Mult entero o real) División / CLK/2 , 10 ns / 2 ns (resultado sin Unidad) Módulo Mod 6 mod 4 ( = 2 ), (-6) mod 4 ( = 2 ), 6 mod (-4) ( = -2) Residuo Res 6 res 4 ( = 2 ), (-6) res 4 ( = - 2 ), 6 res (-4) ( = 2) Exponenciación ** A**2 ( A*A ), B**3 ( B*B*B ), C*0.5 ( Ilegal ) Valor Absoluto Abs Abs 1 ( = 1 ), Abs ( - 1) ( = 1 ), Abs ( 5*(-2) ) ( = 10 ) Operadores aplicables en cada tipo de datos Enteros Reales Tiempo Todos +, -, /, abs ** con el 2o. Operando Entero +, -, / (Ambos de Tiempo) *, / (Uno entero o real) F. Santiago E. 13 Operadores Relacionales : OPERADOR SIMBOLO Igual a = No igual a /= Menor que < Menor o igual que <= Mayor que > Mayor o igual que >= Operadores de Desplazamientos : ( Aplicables a Bit_Vector o Arreglos Booleanos ) SLL – Desplazamiento lógico a la Izquierda. SLL ( 7 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 ) 0 7 6 5 4 3 2 1 0 1 0 0 1 1 0 1 0 SLR – Desplazamiento lógico a la Derecha. Estos operadores se aplican sobre los tipos: Booleanos, Bits, Caracteres, Enteros, Reales, Tiempo, Cadenas y Bit_Vector (ambos del mismo tipo). SLR ( 7 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 ) 0 El resultado siempre es Booleano: True o False 7 6 5 4 3 2 1 0 0 0 1 0 0 1 1 0 A <= B SLL 1; F. Santiago E. 14 SLA – Desplazamiento Aritmético a la Izquierda. SLA ( 7 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 7 6 5 4 3 2 1 1 0 0 1 1 0 1 7 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 0 7 6 5 4 3 2 1 0 1 1 0 0 1 1 0 1 0 ) SRA – Desplazamiento Aritmético a la Derecha. SRA ( ROL – Rotación a la Izquierda. 7 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 7 6 5 4 3 2 1 0 0 1 0 0 1 1 ROL ( ROR – Rotación a la Derecha. 7 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 0 7 6 5 4 3 2 1 0 0 0 0 1 0 0 1 1 0 ) ) ROR F. Santiago E. ( ) 15 Operador de Concatenación : Facilita la creación de nuevos arreglos a partir de arreglos existentes, los arreglos pueden ser de cualquier tipo, pero solo de una dimensión. 0 1 2 3 4 5 6 7 1 0 1 1 0 0 1 0 0 1 2 3 4 5 6 7 Data2 : Bit_Vector ( 0 to 7 ); 0 0 1 0 1 0 1 0 BitOne : bit; 1 Ejemplo: Data1 : Bit_Vector ( 0 to 7 ); VecRes : Bit_Vector ( 0 to 7 ); VecRes <= ( Data1( 0 to 3 ) & Data2 (3 to 5) & BitOne ); 0 1 2 3 4 5 6 7 1 0 1 1 0 1 0 1 F. Santiago E. 16 Asignación de Expresiones a Señales El operador de asignación es : <= Señal_Destino <= Expresión Ejemplos: k <= ‘1’; m <= “0101”; n <= m & k; a <= b or c; x <= y <= z; RETRASO INERCIAL La cláusula “after” impone un retraso inercial, es decir, dos cambios subsecuentes de una entrada son ignorados si el tiempo entre ellos es más corto que el retraso especificado. SWITCH Una asignación puede ser retrasada, la cláusula “after” permite definir esos retrasos 0 6 10 LAMP 0 Retrazo 4 seg 10 12 SWITCH 0 Lamp <= switch after 4s; 4 2 10 LAMP 0 F. Santiago E. 4 17 RETRASO DE TRANSPORTE El “retraso Inercial” es común en muchos sistemas electrónicos, pero no en todos. Por ejemplo en una línea de transmisión los retardos en la propagación son independientes del ancho de los pulsos. Este tipo de retrasos se les conoce como retrasos de transporte y en VHDL se modelan con la palabra reservada “transport”. Retrazo 4 seg Lamp <= transport switch after 4s; SWITCH 0 2 10 LAMP 0 4 6 F. Santiago E. 10 18 Comparación de Retrasos Out1 <= Input after 3s; -- Retraso inercial (default) Out2 <= transport Input after 3s; -- Retraso de transporte INPUT 0 4 10 12 OUT1 0 3 7 10 0 3 7 10 OUT2 13 15 Nota: Los retrasos son útiles para modelado y simulación, pero no se pueden sintetizar. F. Santiago E. 19 Constantes Juegan el mismo papel que los parámetros genéricos, excepto que las constantes se declaran en la arquitectura (y no en la entidad). La declaración de constantes requiere de la Sintaxis siguiente: • Palabra reservada Constant • Nombre de la constante (es un Identificador) • Dos puntos • Indicación del tipo de constante • Valor de la constante después de := • Punto y coma al terminar la línea Architecture Arch1 of Ent1 is Constant t_prop : time := 10nS; Begin .... End architecture Arch1; Block_1 : block Constant N : integer := 123; Begin .... End block Block1; F. Santiago E. P1 : process( A, B) Constant t_hold : time := 5 ns; Begin .... End process P1; 20 Las constantes pueden utilizarse para : • Especificar el tamaño de Objetos complejos (arreglos o buses) • Controlar ciclos repetitivos • Definir parámetros de tiempo como : retrasos, tiempos de conmutación, etc. Nota: No pueden usarse para definir los tamaños de vectores en los puertos , por que los puertos son declarados en las entidades y las constantes se definen en las arquitecturas (solo se puede hacer si la constante está en un paquete usado por la entidad). UBICACIÓN DE LA DECLARACION DECLARACION VISIBILIDAD PARÁMETROS GENERICOS CONSTANTES Sólo en la Entidad ( cláusula generic ) En una arquitectura o En un paquete Es una lista: Generic ( name : tipo := valor_op; name : tipo := valor_op ); Una declaración por constante : Constant name1 : tipo := valor1; Constant name2 : tipo := valor2; En la entidad, incluyendo los puertos y en todas las arquitecturas asociadas con esa Entidad En la arquitectura (si ahí se declaro). En cualquier Unidad de diseño que use el paquete (si se declaró en un paquete), esto incluye entidades y arquitecturas. F. Santiago E. 21 VI. Especificación del Comportamiento F. Santiago E. 22 Introducción El objetivo de un sistema electrónico es transformar datos de entradas en resultados como salidas, esta clase de actividad es conocida como Comportamiento o Funcionalidad del sistema. La especificación del comportamiento consiste en una lista de operaciones que han de ejecutarse para obtener el resultado esperado. Comportamiento de la Máquina: If hay_moneda then botones := habilitados If pres_kiwi then salida <= jugo_kiwi KIWI FRUTAS LIMON Else if pres_frutas then salida <= jugo_frutas Else salida <= jugo_limon Botones := deshabilitado El funcionamiento del distribuidor de bebidas depende de una secuencia de operaciones. Esto es común en muchos sistemas. F. Santiago E. 23 Procesos Un proceso es una manera formal de hacer una lista de operaciones secuenciales. Tiene un formato muy estructurado y representa el comportamiento de una sección de un diseño. Reglas para escribir un proceso: Un proceso se especifica con la palabra reservada Process. Opcionalmente se le puede asignar un nombre, éste debe ir antes de process seguido de dos puntos. El fin del proceso se indica con end process y luego puede repetirse el nombre del proceso. El cuerpo del proceso está formado por una lista de proposiciones que debe iniciar con la palabra reservada begin, la lista termina con el fin del proceso. La declaración de variables o constantes se debe hacer antes de la palabra begin. Plantilla : nom_op : process declaración de variables o constantes begin proposiciones secuenciales end process nom_op; F. Santiago E. 24 Procesos . . . EJEMPLO : SEL A Y B MUX2_TO1 : process Constant High : Bit := ‘1’; begin Y <= A; if SEL = High then Y <= B; end if; End process MUX2TO1; Puesto que VHDL es para representar sistemas, la terminación de un proceso se debe analizar a detalle. Un sistema no realiza sus funciones sólo una vez y termina; más bien, debe repetir sus actividades en un ciclo infinito. Por eso, un proceso asegura que terminada la ejecución de la última proposición, inmediatamente iniciará nuevamente con la primera. Como resultado Un proceso Nunca Termina. SomeProcess : Process Begin Some Statement1; Some Statement2; Some Statement3; Some Statement4; End process SomeProcess F. Santiago E. 25 Necesidad de Suspender y Reanudar un Proceso Los dispositivos electrónicos operan en un ciclo infinito; después de su activación ejecutan una lista de tareas para después regresar a esperar una condición de repetición. En otras palabras, los dispositivos suspenden su operación cuando completan sus tareas y las reanudan cuando se dan nuevamente las condiciones. KIWI FRUTAS LIMON La inserción de una moneda dará inicio a las actividades de la máquina, que se “suspenderán” después de que la máquina proporcione el jugo deseado. Las actividades se “reanudarán” cuando ocurra la inserción de otra moneda. Esta suspensión temporal en VHDL se puede realizar con la sentencia wait. La sentencia wait sirve para suspender un proceso una vez que ha completado su tarea y reanudarlo cuando se da la condición que finaliza la espera. F. Santiago E. 26 Sentencia Wait Wait puede usarse para: - Detener incondicionalmente la ejecución temporal de un proceso. - Listar las condiciones necesarias para que el proceso se reanude. Si un proceso contiene una sentencia Wait, ejecutará todas sus proposiciones hasta que el wait sea encontrado, ahí esperará hasta que se cumplan las condiciones establecidas en el wait. Tipos de Wait : 1.- Wait for cierto_tiempo : Suspende el proceso por una cantidad específica de tiempo, el tiempo se puede expresar explícitamente: Wait for 10 ns; O bien como una expresión: Wait for CLK_Periodo / 2; F. Santiago E. 27 Sentencia Wait 2.- Wait until condición : El proceso se suspende hasta que una condición llega a ser verdadera, debido a algún cambio en las señales involucradas. Ejemplos: Wait until CLK = ‘1’; Wait until CE and (not RESET); Wait until IntData > 16; 3.- Wait on lista de sensibilidad : El proceso se suspende hasta que ocurre un evento en cualquiera de las señales que integran la lista de sensibilidad Ejemplos: Wait on CLK; Wait on Enable, Data; 4.- Wait complejo : Contiene una combinación de más de uno de los 3 tipos mencionados anteriormente. Ejemplos: Wait on Data until CLK = ‘1’; Wait until CLK = ‘1’ for 10 ns; F. Santiago E. 28 La sentencia wiat puede ubicarse en cualquier parte del proceso, en realidad depende del comportamiento deseado. Process Begin wait on sigA; proposiciones 1; proposiciones 2; proposiciones 3; End process; Process Begin proposiciones 1; proposiciones 2; proposiciones 3; wait on sigB; End process; El wait sobre la lista de sensibilidad es probablemente la forma más frecuente de reanudar procesos en VHDL, es por eso que el lenguaje permite colocar la lista de sensibilidad entre paréntesis, justo después de la palabra process. Su funcionamiento es similar a un wait on lista al final del proceso. Process Begin proposiciones 1; proposiciones 2; proposiciones 3; wait on señales; End process; Process ( señales ) Begin proposiciones 1; proposiciones 2; proposiciones 3; End process; F. Santiago E. 29 Un proceso puede tener múltiples wait’s, pero si tiene una lista de sensibilidad, no es necesario que tenga un wait explícito para suspender su ejecución. Cuando la ejecución de un proceso inicia, ésta se realiza una vez, posteriormente el proceso es suspendido hasta que alguna señal en su lista de sensibilidad cambia de valor. Aunque sólo una de las señales de la lista cambie, con ello todas las proposiciones del proceso se ejecutan en forma secuencial, no solo aquellas que involucran a la señal que cambió. Process ( signal1, signal2, signal3 ) Begin signal1 <= expresion 1 ; signal2 <= expresion 2; signal3 <= expresion 3; End process; F. Santiago E. 30 Señales en Procesos El propósito de una implementación en VHDL es describir la reacción de las salidas ante las entradas. Tanto entradas como salidas son señales, de modo que tal reacción básicamente esta dada por asignaciones de señales. Las señales y sus asignaciones se manejan en procesos, sin embargo, su uso está gobernado por 3 restricciones: 1. 2. 3. Las señales no pueden declararse dentro de procesos. Cualquier asignación de una señal tomará efecto cuando el proceso se suspende. Mientras esto no ocurra, todas las señales mantendrán sus previos valores. Sólo la última asignación de una señal dentro de un proceso es efectivo. No tiene sentido asignar mas de un valor a una señal en un proceso dado. Ejemplo: Process ( signal1, signal2, signal3 ) Begin Proposición 1; Proposición 2; signal3 <= signal1 + 3; End process; F. Santiago E. Signal1 = 0 -> 1 Signal2 = 0 Signal3 = 5 31 Las restricciones en el uso de señales impactan en sus aplicaciones prácticas. Dado que sólo pueden almacenar el valor de su última asignación, no pueden usarse para almacenamientos intermedios o de datos temporales (dentro de un proceso). Otro inconveniente es el siguiente, como los nuevos valores se asignan sólo al suspender el proceso, el análisis llega a ser complicado. Ejemplo: Process ( C, D ) Begin A <= 2; B <= A + C; A <= D + 1; E <= A*2; End process; A=1 B=1 C=1 D=1 E=1 Si D cambia a 2 ¿Qué pasa? Es necesario contar con otro tipo de objetos que permitan almacenar datos temporales. Estos objetos son las variables, cuya única diferencia con las señales es que se pueden utilizar donde una señal no es aplicable. F. Santiago E. 32 Ejemplo: Process ( C, D ) variable Av, Bv, Ev : integer := 0; Begin Av := 2; BV := Av + C; Av <= D + 1; Ev <= Av*2; A <= Av; B <= Bv; E <= Ev; End process; A=1 B=1 C=1 D=1 E=1 Av = 0 Bv = 0 Ev = 0 Si D cambia a 2 ¿Qué pasa? Una señal tiene 3 propiedades asociadas: Tipo, valor y tiempo. Con una relación cerrada entre valor y tiempo, ya que cada señal tiene una trayectoria de valores a través del tiempo. Una variable sólo tiene 2 propiedades: tipo y valor, por lo que solo se puede conocer su valor actual. Si las señales y variables son del mismo tipo, indistintamente puede haber asignaciones ente ellas. F. Santiago E. 33 SEÑALES VARIABLES Se declaran como puertos en las entidades o en Como tienen carácter local, solo pueden las partes declarativas de las arquitecturas, pero declararse en procesos o subprogramas. No no en los procesos. fuera de ellos. La asignación de un nuevo valor a una señal solo tiene efecto cuando el proceso es suspendido. Por lo que sólo la última asignación es válida. Las auto-asignaciones como: Sig1 <= Sig1 + 1 Sólo son posibles con señales internas o del tipo inout, si son externas. Toman sus nuevos valores inmediatamente. Todos son efectivos, de modo que en un proceso puede haber múltiples asignaciones a una variable. Las auto-asignaciones como: Var1 := Var1 + 1 Son válidas y muy usadas en ciclos repetitivos. Es posible retrasar la asignación de una señal (con la cláusula after ), hay dos tipos de retrasos: El retraso inercial y el de transporte. No es posible retrasar la asignación de una variable. F. Santiago E. 34 Control de Flujo Para el control de flujo VHDL tiene las siguientes proposiciones : - Condicionales : If . . . . Then . . . . . - Condicionales con alternativas: If . . . . Then . . . . . Else . . . If . . . . Then . . . . . Elsif . . . Then . . . . . Else . . . - De elección múltiple: Case . . . . Is when . . . . -Ciclos repetitivos: While . . . . Loop . . . . ( Repetitivo por condición ) for . . . . Loop . . . . ( Repetitivo por contador ) Con estas estructuras de control, el flujo de la ejecución de las instrucciones ya no sólo es secuencial. F. Santiago E. 35 if Cond1 ExProc : Process ( Lista_de_sensibilidad ) then else Begin if Cond1 then . . . . . . . while Cond3 loop . . . case Cond2 is case Cond2 is when val1 => . . . . when val2 => . . . . val1 val2 others when others => . . . . for l in 1 to 4 loop . . . . for l in 1 to 4 loop . . . . . . . . end loop; end case; . . . . else end case; while Cond3 loop . . . . end loop; . . . . end if; end if; . . . . . . . . End process End process F. Santiago E. 36 Ejemplo: Estructura if - then FLIP FLOP TIPO D D Q CLK -- Descripción de la Entidad Entity Flip_flop_D is port ( D : in Bit; CLK : in Bit; Q : out Bit ); End Flip_flop_D; -- Descripción de la Arquitectura Architecture unica of Flip_flop_D is Begin process ( CLK ) begin if CLK = ‘1’ then Q <= D; end if; end process; End unica; F. Santiago E. 37 if – then (anidados) FLIP FLOP TIPO D CON RESET SÍNCRONO D Q CLK RST -- Descripción de la Entidad Entity FFD_SR is port ( D , CLK, RST : in Bit; Q : out Bit ); End FFD_SR; -- Descripción de la Arquitectura Architecture unica of FFD_SR is Begin process ( CLK ) begin if CLK = ‘1’ then if RST = ‘1’ then Q <= ‘0’; else Q <= D; end if; end if; end process; End unica; F. Santiago E. 38 if – then – elsif FLIP FLOP TIPO D CON RESET ASÍNCRONO D Q CLK RST -- Descripción de la Entidad Entity FFD_AR is port ( D, RST, CLK : in Bit; Q : out Bit ); End FFD_AR; -- Descripción de la Arquitectura Architecture unica of FFD_AR is Begin process ( RST, CLK ) begin if RST = ‘1’ then Q <= ‘0’; elsif CLK = ‘1’ and CLK’event then Q <= D; end if; end process; End unica; F. Santiago E. 39 Ejemplo: Estructura de múltiples decisiones COMPUERTA PROGRAMABLE Dato1 Salida Dato2 Modo Modo Salida 000 Dato1 AND Dato2 001 Dato1 OR Dato2 010 Not ( Dato1 AND Dato2) 011 Not ( Dato1 OR Dato2) 100 Not ( Dato1 ) 101 Not ( Dato 2 ) 110 o 111 0 -- Descripción de la Entidad Entity Gate_Prog is port ( Dato1, Dato2 : in Bit; Modo : in Bit_Vector ( 2 downto 0 ); Salida : out Bit ); End Gate_Prog; -- Descripción de la Arquitectura Architecture Gate_Prog of Gate_Prog is Begin process ( Modo, Dato1, Dato2 ) begin case Modo is when “000” => Salida <= Dato1 and Dato2; when “001” => Salida <= Dato1 or Dato2; when “010” => Salida <= Dato1 nand Dato2; when “011” => Salida <= Dato1 nor Dato2; when “100” => Salida <= not Dato1; when “101” => Salida <= not Dato2; when others => Salida <= ‘0’; end case; end process; End Gate_Prog; F. Santiago E. 40 Ejemplo: Ciclo repetitivo por Condición Un contador de Pulsos cuya salida (en binario) indique cuantos pulsos ocurrieron mientras una señal (Level) estuvo en alto. Contador de Pulsos CLK Level Q(0) Q(1) Q(2) Q(3) 0 1 0 0 -- Descripción de la Entidad Entity Conta_Pulsos is port ( CLK : in STD_LOGIC; Level : in STD_LOGIC; Q : out STD_LOGIC_VECTOR ( 3 downto 0 ) ); End Conta_Pulsos; -- Descripción de la Arquitectura Architecture Conta_Pulsos of Conta_Pulsos is Begin process Variable cuenta : STD_LOGIC_VECTOR (3 downto 0) := “0000”; begin Q <= cuenta; wait until level = ‘1’; cuenta := “0000”; while level = ‘1’ loop wait until clk = ‘1’; if level = ‘1’ then cuenta := cuenta + 1; end if; wait until clk = ‘0’; end loop; end process; End Conta_Pulsos; F. Santiago E. 41 Ejemplo: Ciclo repetitivo por Contador -- Descripción de la Entidad library IEEE; use IEEE.std_logic_1164.all; Circuito que invierte un vector (Bit por Bit) Ent 7-0 Sal 7-0 7 Ent : 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 7 Sal : entity inv_vec is generic ( ancho_bus : integer := 8 ); port ( ent: in STD_LOGIC_VECTOR (ancho_bus - 1 downto 0); sal: out STD_LOGIC_VECTOR (ancho_bus - 1 downto 0) ); end inv_vec; 6 5 4 3 2 1 0 0 1 0 0 1 1 0 1 -- Descripción de la Arquitectura Architecture inv_vec of inv_vec is begin process ( ent ) variable cont : integer; begin for cont in 0 to ancho_bus - 1 loop sal( cont ) <= ent (ancho_bus - cont - 1); end loop; end process; end inv_vec; F. Santiago E. 42 Ruptura de ciclos Los ciclos while y for ejecutarán sus proposiciones siempre que sus condiciones de evaluación sean verdaderas. Sin embargo, en ocasiones es deseable una salida obligada del ciclo o bien saltarse una iteración e ir a la siguiente. Por ejemplo, en un contador de bits con valor ‘1’ en un vector, si el bit a evaluar contiene cero, inmediatamente se puede pasar a la iteración siguiente, esto se hace con la cláusula next : process ( DataBus ) variable NumOfOnes : integer := 0; begin for Cont in 0 to 7 loop next when DataBus( Cont ) = ‘0’; NumOfOnes := NumOfOnes + 1; end loop; Ones <= NumOfOnes; end process; F. Santiago E. 43 Cuando lo que se quiere es terminar con el ciclo, la cláusula a usar es exit. En el proceso mostrado en el anterior ejemplo, si se quisieran contar los 1’s menos significativos, antes de que aparezca el primer cero, el proceso cambia a : process ( DataBus ) variable NumOfOnes : integer := 0; begin for Cont in 0 to 7 loop exit when DataBus( Cont ) = ‘0’; NumOfOnes := NumOfOnes + 1; end loop; Ones <= NumOfOnes; end process; F. Santiago E. 44 Ejercicios Multiplexor de 1 bit, de 4 canales a 1 Comparador de 4 bits Registro de 8 bits con carga paralela, con habilitación externa y reset asíncrono. Sumador completo de 4 bits Nota: Acondicionar para implementar en la tarjeta Nexys 2. F. Santiago E. 45