Capı́tulo 1 Representación digital de los datos Conceptos básicos Dato Digital Sistema decimal Sistemas posicionales Sistema Binario Sistemas Octal y Hexadecimal Conversiones de base Números con signo Números reales Aritmética Códigos Representación digital de los datos Saber Hacer Representar cantidades enteras en cualquier base, principalmente en binario. Seleccionar la forma de representación de datos numéricos. Representar en forma digital cualquier tipo de datos (numéricos y no numéricos). 1 2 CAPÍTULO 1. REPRESENTACIÓN DIGITAL DE LOS DATOS El mundo moderno gobernado por la informática, nos dice que la “información” puede ser procesada, enviada de un sitio a otro o almacenada. Lo que llamamos información puede consistir simplemente en un texto, es decir, una hilera de caracteres en una página de un directorio telefónico o puede contener imágenes y sonido como la novedosa “multimedia” nos tiene acostumbrados. Dentro de este conjunto de información también se incluyen los datos numéricos; al fin y al cabo, el computador fue conocido inicialmente por su habilidad de hacer cálculos aritméticos. Nuestro interrogante podrı́a ser: ¿Cómo están constituidas todas estas categorı́as de datos para que sean “manipuladas” por medio de una máquina? ¿Cómo está constituida la información que maneja un teléfono? Alguien seguramente se acordará, o hasta lo habrá visto en los comerciales de los teléfonos celulares, que algunos son digitales y otros son análogos o analógicos. Ya lo entendimos? Seguramente que no. Examinemos otra de estas famosas máquinas: la calculadora; no hay duda de que el asunto es digital puesto que los datos que manipula la calculadora están conformados por dı́gitos. En una calculadora programable, una parte del teclado corresponde a las letras del alfabeto; además, podemos procesar datos numéricos, almacenar las direcciones y los teléfonos de todos nuestros amigos. Es muy probable que nuestra calculadora ya tenga pantalla y pueda mostrar gráficas. Esta pantalla es similar a una hoja de papel cuadriculado sólo que con los cuadritos más diminutos; cada cuadrito se denomina “pixel” y simplemente, el puede estar “encendido” o “apagado”. Ha notado que cuando hacemos gráficas en papel milimetrado, lo que hacemos es ubicar puntos y después los unimos por una lı́nea continua? Pues algo parecido hace la calculadora con las gráficas, sólo que no tiene que unir la lı́nea; de eso se encarga el ojo humano si los puntos son muy pequeños y están muy cerca unos de otros. Empezamos a concentrarnos entonces en dı́gitos más pequeños; en este caso, los pixeles están “encendidos” o “apagados”; o también en 1 o en 0. A estos dı́gitos de sólo dos estados los llamamos “bits”, “bitios”, o dı́gitos binarios (la palabra dı́gito implı́citamente contiene el significado de decimal o sea que puede tener 10 valores diferentes (0,1,2. . . 9). Los bits son muy importantes en el mundo “digital” puesto que son los más inmediatos de representar fı́sicamente; un relé, por ejemplo, puede estar abierto o cerrado (los primeros computadores fueron construidos con relés); un transistor puede estar conduciendo o estar en corte. Queremos examinar entonces cómo es posible la representación de cualquier tipo de información a partir de los bits o dı́gitos binarios. 1.1 DIGITAL VRS. ANALÓGICO Empecemos por definir lo que es un sistema: En primer lugar, entendemos por sistema un conjunto de elementos que en forma coordinada tienen una función especı́fica; desde el punto de vista matemático, un sistema es una transformación única u operador que relaciona o transforma una condición de entrada dada en una salida especı́fica. Un sistema cuyas señales de entrada y de salida son continuas, decimos que es un sistema continuo o 1.2. SISTEMAS DE NUMERACIÓN POSICIONALES 3 analógico. E igualmente, un sistema cuyas señales de entrada y de salida no son continuas, es decir discretas o muestreadas, es un sistema digital. Estamos en el punto de partida de los sistemas digitales, los cuales se pueden definir como aquellos que manejan toda su información representada en forma digital, es decir, basada en dı́gitos generalmente binarios. Esto nos permite ver por qué algunos relojes, por ejemplo, son digitales. Pero entonces, cómo son los relojes análogos? Los surtidores de gasolina son digitales. Y los teléfonos digitales?. La información procesada por los teléfonos, es la voz humana, Esta señal, como ya sabemos, es intrı́nsecamente continua (no es escalonada): una señal de sonido variable en el tiempo; el teléfono lo que hace es convertir esta señal de sonido en una señal de corriente eléctrica, igualmente continua, que es equivalente o “análoga” a la señal original. Fundamentalmente, esto es lo que ocurre con todas las variables de un sistema fı́sico cuando les aplicamos instrumentos de medida: el instrumento de medida o transductor nos produce una señal generalmente eléctrica que es análoga o equivalente a la original; esta señal puede variar gradualmente sobre un intervalo continuo de valores. La señal continua descrita anteriormente se puede “discretizar”, “digitizar”, “digitalizar” o “muestrear”, lo cual significa tomar valores o “muestras” cada cierto tiempo; algo similar hacemos cuando una señal en lugar de ser representada por una gráfica continua, es mostrada como una tabla de valores los cuales ya son digitales. En consecuencia, el teléfono digital trabaja con la señal que representa la voz en forma digital; algo similar ocurre con los equipos de sonido digitales y con los osciloscopios digitales. El mundo real está fundamentalmente compuesto de señales continuas que se procesan en forma digital. 1.2 SISTEMAS DE NUMERACIÓN POSICIONALES En un sistema de numeración posicional, un número se representa por una hilera de dı́gitos, cada uno de los cuales tiene un peso asociado que depende de la posición que ocupe. Por ejemplo: 1734 = 1×1000 + 7×100 + 3×10 + 4×1 El peso de cada dı́gito resulta de una potencia de 10 correspondiente a la posición del dı́gito. En general, si D = d3 d2 d1 d0 d−1 d−2 . Entonces, D = d3×103 + d2×102 + d1×101 + d0 + d−1×10−1 + d−2×10−2 Este sistema de numeración tiene como base o raı́z a 10 por lo cual se le denomina decimal. En general, podemos construir otros sistemas de numeración tomando otras bases que deben ser números enteros. 4 CAPÍTULO 1. REPRESENTACIÓN DIGITAL DE LOS DATOS En el sistema decimal se utilizan 10 dı́gitos para representar las cantidades. En el sistema cuaternario, o sea el que tiene como raı́z 4, los dı́gitos son 0,1,2,3 (en todos los sistemas posicionales interviene el 0 lo cual contrasta con el sistema de números romanos que no tiene cero) Si vamos a contar en el sistema cuaternario, tendremos: DECIMAL 0 1 2 3 4 5 6 7 8 9 CUATERNARIO 0 1 2 3 10 11 12 13 20 21 Cuadro 1.1: Observamos que 134 (13 en base 4) equivale a: 1×41 + 3 = 4 + 3 = 710 Por lo tanto, 312014 = 3×44 + 1×43 + 2×42 + 0×41 + 1×40 = 768 + 64 + 32 + 1 = 86510 El sistema binario tiene como base 2 y sus dı́gitos binarios (bits) son 0 y 1. Observemos como se puede contar en el sistema binario: DECIMAL 0 1 2 3 4 5 6 7 BINARIO 0 1 10 11 100 101 110 111 DECIMAL 8 9 10 11 12 13 14 15 BINARIO 1000 1001 1010 1011 1100 1101 1110 1111 Cuadro 1.2: Si con dos dı́gitos decimales podemos contar desde 0 hasta 99, tendremos 100 = 102 cantidades diferentes; en forma análoga, podemos contar con 4 bits desde 0 hasta 1111, o sea 24 = 16 cantidades diferentes. 1.3. REPRESENTACIONES DE CANTIDADES NUMÉRICAS 5 Si la base es superior a 9, tendremos que usar otros dı́gitos adicionales para los cuales se usan las letras mayúsculas del alfabeto. Por ejemplo, si la base es 16, los dı́gitos son 0,1,2,...,9,A,B,C,D,E,F; donde A es el equivalente a 10, B a 11 y ası́ sucesivamente hasta F = 15. Este sistema de numeración se denomina “hexadecimal”. En sistemas digitales el sistema de numeración básico es el binario, pero el octal y el hexadecimal son importantes puesto que 8 y 16 son potencias de 2. Esto nos permite convertir fácilmente de binario a octal o hexadecimal y viceversa en forma muy rápida y obtener representaciones más compactas de cantidades binarias. 1.3 REPRESENTACIONES DE CANTIDADES NUMÉRICAS Para representar información en el computador utilizamos códigos, los cuales se forman a partir de un conjunto dado de sı́mbolos utilizados en forma sistemática y normalizada. Un código muy conocido en nuestra vida diaria es el que se utiliza en el semáforo: si la luz verde está encendida, significa siga, si la luz roja está encendida, debemos detenernos; y si la luz amarilla está encendida, significa precaución. El código Morse es otro ejemplo bien conocido en el cual utilizamos los sı́mbolos punto y raya para representar todos los caracteres del alfabeto. Este código permitió el envı́o de mensajes por medio del telégrafo. La información que necesitamos manipular en forma digital generalmente la clasificamos en numérica y no numérica. Dentro de la información numérica a su vez podemos encontrar clasificaciones numéricas de punto fijo y de punto flotante. 1.3.1. Números de punto fijo Los números de punto fijo se utilizan para representar ya sea enteros con signo o fracciones con signo. En ambos casos se utilizan los sistemas de magnitud y signo, de complemento de dos, o de complemento de uno para representar los valores con signo. Los enteros de punto fijo tienen un punto binario implı́cito a la derecha del bit menos significativo y las fracciones de punto fijo tienen el punto binario implı́cito entre el bit del signo y el bit de magnitud más significativo. Los números en el sistema de magnitud y signo constan de una magnitud y además, de un sı́mbolo que indica si la magnitud es positiva o negativa. Cuando los números son binarios se utiliza un bit adicional para representar el signo; usualmente es el bit más significativo. Por ejemplo: 010101012 = +8510 011111112 = +12710 000000002 = +010 110101012 = −8510 111111112 = −12710 100000002 = −010 En el sistema de complemento de la base, el complemento de un número de n dı́gitos se obtiene al restarlo de rn , donde r es la base. En el sistema decimal el complemento de la 6 CAPÍTULO 1. REPRESENTACIÓN DIGITAL DE LOS DATOS base se llama complemento de 10, mientras que en el sistema binario, se llama complemento de 2. Ejemplo: 184910 → 10000 − 1849 8151 ← 104 101012 → Complemento de 10 100000 10101 100000 ← 25 Complemento de 2 Una forma rápida de encontrar el complemento de 2 consiste en complementar cada bit (cambiar 1 por 0 y viceversa) y sumarle uno al resultado. Entonces, si 1710 = 000100012 el complemento de 2 será: 11101110 +1 111011112 En el sistema de complemento de la base disminuida, el complemento de un número de n dı́gitos se obtiene al restarlo de rn − 1. En el sistema decimal el complemento de la base se llama complemento de 9; y en el sistema binario se llama complemento de 1 que se calcula rápidamente complementando cada bit individualmente. Entonces, si 1710 = 000100012 el complemento de 1 de 1710 será: 111011102 1.3.2. Números de punto flotante Para representar cantidades numéricas que pudieran tener parte fraccionaria y con magnitud muy grande o muy pequeña, se inventó la codificación de números de punto flotante, basándose seguramente en la notación cientı́fica. En general, la forma de punto flotante de un número N se escribe como: N = M × rE En donde M, la mantisa, es un número de punto fijo que contiene los dı́gitos significativos de N. El exponente E, es un entero de punto fijo. La mantisa M, usualmente se codifica en magnitud y signo, por lo general como una fracción, y se puede escribir como: M = SM an−1 · · · a−m El exponente E se codifica en el complemento de dos con exceso de -K, el cual se forma sumando un sesgo K al valor entero como complemento de 2 del exponente. Los formatos de punto flotante utilizados por los sistemas de cómputo de los diversos fabricantes, difieren con frecuencia en la cantidad de bits que se usan para representar la mantisa y el exponente, ası́ como en el método de codificación de cada uno. El estándar 754 de 1985 del IEEE define 2 formatos de números de punto flotante, ası́: 1.4. REPRESENTACIÓN DE INFORMACIÓN NO NUMÉRICA Total de bits Bits de la mantisa Bits del exponente Sesgo del exponente PRECISION SENCILLA 32 23 8 127 7 PRECISION DOBLE 64 52 11 1023 Cuadro 1.3: 1.4 REPRESENTACIÓN DE INFORMACIÓN NO NUMÉRICA En esta categorı́a caben muchas cosas tales como el texto, las imágenes, el sonido, etc. El tipo más común de datos no numéricos es el texto, cadenas de caracteres de algún conjunto de datos. Cada carácter está representado en el computador mediante una cadena de bits de acuerdo con una convención establecida. El código de caracteres más comúnmente usado es el ASCII (American Standard Code for Information Interchange). ASCII representa cada carácter con una cadena de 7 bits, la cual da un total de 128 caracteres diferentes. El código BCD (Binary-Coded Decimal) sirve para representar los dı́gitos decimales del 0 al 9 y es un ejemplo de un código ponderado, es decir, cada posición en el código tiene un valor o un peso numérico asociado a éste. El código BCD utiliza 4 bits y los pesos son los mismos que en un entero binario de 4 bits. El código BCD también es conocido como código 8-4-2-1 por los pesos utilizados. Un código cı́clico se puede definir como un código en el que un corrimiento circular produce otra cadena del código para cualquier palabra de código. El código Gray es uno de los tipos más comunes de códigos cı́clicos y tiene la caracterı́stica de que las palabras de código para dos números consecutivos difieren sólo en un bit. Es decir, la distancia entre dos palabras de código es 1. En general, la distancia entre dos palabras de código binario es igual al número de bits en el que difieren las dos palabras. El código Gray es útil donde se necesite medir u observar la posición de un eje circular. En la figura 1.1 observamos esta aplicación en forma esquemática. 1.5 PROCESAMIENTO ELECTRÓNICO DE LOS DATOS Hasta este punto ya tenemos un panorama general de la forma como los datos pueden representarse. El término procesamiento es muy amplio e incluye actividades tales como la comunicación (muy utilizada cuando enviamos un correo electrónico), el almacenamiento, la ejecución de cálculos numéricos, etc. En la Figura 1.2 se muestran los elementos que intervienen en el procesamiento de los datos. El procesador es el agente ejecutor de la actividad; puede ser una persona (en cuyo caso el proceso es manual) o puede ser un computador. Este modelo lo podemos aplicar 8 CAPÍTULO 1. REPRESENTACIÓN DIGITAL DE LOS DATOS Figura 1.1: Disco con código Gray. ENTRADA DE DATOS → PROCESADOR → SALIDA DE RESULTADOS Figura 1.2: Procesamiento de datos. al computador personal, en el cual la entrada de datos se realiza mediante dispositivos como el teclado, el ratón, etc.; y la salida de resultados se realiza por dispositivos como la pantalla y la impresora. El procesamiento lo hace la Unidad Central de Procesamiento o CPU. Podemos pensar también, en utilizar el computador como elemento de control en un sistema. Muy seguramente la variable que se va a controlar será de tipo analógico, por lo cual la entrada de datos la realizará un dispositivo convertidor análogo/digital. La labor de procesamiento en este caso consistirá en comparar la variable controlada contra el valor de referencia y emitir la señal de control, obviamente digital. El módulo de salida será entonces un convertidor digital/análogo. Capı́tulo 2 Compuertas Lógicas y Álgebra Digital Conceptos básicos Variables lógicas o binarias Álgebra de Boole Leyes Booleanas Postulados del Álgebra Booleana Tablas de Verdad Compuerta AND Compuerta OR Compuerta NOT Compuerta NAND Compuerta NOR Compuerta EXOR Compuerta NEXOR Tabla de Verdad Saber Hacer Reconocer los sı́mbolos de las operaciones lógicas. Manipular ecuaciones lógicas usando conceptos de álgebra booleana. 9 10 2.1 CAPÍTULO 2. COMPUERTAS LÓGICAS Y ÁLGEBRA DIGITAL ALGEBRA DE BOOLE En 1854 el matemático inglés George Boole escribió el libro “An Investigation of the Laws of thought on which to found the Mathematical Theories of Logic and Probabilities” , en el cual se hizo un análisis matemático de la lógica, que dio como resultado un nuevo campo denominado ”Álgebra de la Lógica”, o “Álgebra Booleana”. En 1938, Claude E. Shannon, asistente de investigación del Departamento de Ingenierı́a Eléctrica del MIT (Massachussets Institute of Technology), sugirió la posibilidad de utilizar el álgebra booleana en el diseño de circuitos de conmutación basados en relés, con lo cual se sentaron las bases matemáticas de los circuitos de conmutación utilizados en los computadores digitales. Los estados lógicos y los estados de un circuito de conmutación se caracterizan por las siguientes propiedades: Existen dos estados; usualmente, “verdadero” y “falso” o “1” y ”0”. Cualquier variable debe existir en uno de los dos estados; no se permiten otros estados. Cualquier variable lógica sólo puede tener un valor. Ninguna cantidad puede ser simultáneamente ”verdadera” y ”falsa”. Toda cantidad tiene un opuesto. Si la cantidad es “verdadera”, el opuesto es el inverso. Una cantidad lógica puede ser una constante o una variable. Las cantidades lógicas se pueden representar fı́sicamente de muchas maneras, tales como: • Eléctricamente, con dos voltajes diferentes. • Mecánicamente, por la posición de un conmutador. • Óptimamente, por la presencia o ausencia de luz. Tomando como entradas las cantidades lógicas, el álgebra booleana define tres operaciones básicas que son el producto booleano, la suma booleana y el complemento. Ya en el terreno de los sistemas digitales, estas operaciones se convierten en compuertas, las cuales definimos a continuación, junto con otras compuertas adicionales que son de utilidad. 2.1.1. La compuerta AND Esta compuerta implementa el producto booleano. La compuerta AND produce una salida verdadera sólo cuando cada una de las entradas es verdadera, tal como se muestra en la siguiente tabla de verdad: 2.1. ALGEBRA DE BOOLE 11 A 0 0 1 1 B 0 1 0 1 F 0 0 0 1 En álgebra booleana, la función AND se indica por medio de un punto entre las entradas (multiplicación lógica) o por multiplicación implı́cita como en álgebra F = A.B F = AB F = (A)(B) 2.1.2. La compuerta OR Esta compuerta corresponde a la suma booleana. La Compuerta OR produce una salida verdadera cuando cualquiera de sus entradas es verdadera. A 0 0 1 1 B 0 1 0 1 F 0 1 1 1 F = AorB F = A + B 2.1.3. La compuerta NOT o INVERSOR Esta compuerta corresponde al complemento booleano. La salida de un inversor es simplemente el complemento de la entrada. A 0 1 F 1 0 F = notA F = A F = A0 2.1.4. La compuerta NAND La salida de la compuerta NAND es el complemento de la salida de la compuerta AND 12 CAPÍTULO 2. COMPUERTAS LÓGICAS Y ÁLGEBRA DIGITAL A 0 0 1 1 B 0 1 0 1 F 1 1 1 0 F = A.B 2.1.5. La compuerta NOR La salida de la compuerta NOR es el complemento de la salida de la compuerta OR. A 0 0 1 1 B 0 1 0 1 F 1 0 0 0 F =A+B 2.1.6. Leyes Booleanas El álgebra Booleana satisface las siguientes leyes o axiomas: N 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Algebra a+a=a a×a = a a + (b + c) = (a + b) + c a×(b×c) = (a×b)×c a+b=b+a a×b = b×a a + (a×b) = a a×(a + b) = a a×(b + c) = (a×b) + (a×c) a + (b×c) = (a + b)×(a + c) a+0=a a×1 = a a×a0 = 0 a + a0 = 1 Ley Ley de Idempotencia Ley asociativa Ley conmutativa Ley de Absorción Ley distributiva 2.2. FUNCIONES DIGITALES O BOOLEANAS 13 En éste punto conviene mencionar que éstas leyes cumplen con el principio de dualidad del álgebra booleana, mediante el cual si intercambiamos suma por producto y 0 por 1, obtenemos otra ley igualmente válida. Obsérvese que 1 y 2 son duales, al igual que 3 y 4, y ası́ sucesivamente. 2.1.7. Postulados del álgebra booleana Los siguientes postulados son de bastante utilidad en la manipulación de expresiones algebraicas. A+A=1 A.A = 0 A.A = A A+A=A A+B =B+A A=A A,0 = 0 A,1 = A A+0=A A+1=1 A+A=A A + AB = A A + AB = A + B (A + B).(A + C) = A + B.C (A + B).B = B A.B + A.C = A.(B + C) A.B = B.A Teorema de DeMorgan: (A.B) = A + B 2.2 (A + B) = A.B FUNCIONES DIGITALES O BOOLEANAS Las expresiones booleanas están conformadas por variables, constantes y operaciones booleanas. Si agregamos los paréntesis como ayuda para significar agrupación, obtenemos la idea más general de expresión, por el estilo de las que utilizamos en los lenguajes de programación. Por ejemplo, a.x1 .(b + (x1 .x2 )) Es una expresión booleana, siempre y cuando a, b, x1 , x2 sean variables booleanas. Las expresiones boolenas también se denominan funciones booleanas. Para n variables booleanas, y utilizando la notación matemática de función, tendrı́amos que f (x1 , x1 , x3 , x4 , · · · , xn ) representarı́a una función booleana que contendrá en su definición las n variables booleanas y también los operadores booleanos. Tomemos como ejemplo un sumador de 4 bits, representado como se muestra a continuación: Las señales de entrada son dos números binarios de 4 bits cada uno, y la respuesta es un número binario de 5 bits. Para definir la función digital se puede utilizar una tabla que contiene todas las combinaciones posibles de las variables de entrada y define para cada posible combinación el 14 CAPÍTULO 2. COMPUERTAS LÓGICAS Y ÁLGEBRA DIGITAL Figura 2.1: Sumador de 4 bits valor de la función. Para éste caso la tabla tendrı́a 28 filas, dado que son 8 variables de entrada, cada una de las cuales puede tener 2 valores diferentes. Estas tablas se denominan tablas de la verdad. Capı́tulo 3 Circuitos Básicos de 2 Niveles Conceptos básicos Tabla de verdad Especificación de un circuito Forma canónica de una ecuación Notación POS Notación SOP Implementación de un circuito usando compuertas básicas Saber Hacer Saber expresar en forma de tabla de verdad una especificación en lenguaje natural de un circuito lógico. Obtener de la tabla de verdad la ecuación canónica del circuito. 15 16 CAPÍTULO 3. CIRCUITOS BÁSICOS DE 2 NIVELES 3.1 FORMA “SUMA DE PRODUCTOS” Supongamos que existe una red digital cuya operación es definida por la tabla siguiente: A 0 0 0 0 1 1 1 1 B 0 0 1 1 0 0 1 1 C 0 1 0 1 0 1 0 1 F 0 0 1 1 1 0 0 1 Cuadro 3.1: Asumiendo que el estado verdadero de una variable es 1 y el estado complementario es 0, directamente podemos escribir la siguiente expresión booleana: F = ABC + ABC + AB C + ABC (3.1) Esta forma de ecuación, una serie de productos (AND) conectado por la suma (OR), la llamamos suma de productos (SOP). 3.1.1. Implementación de un Circuito SOP Una expresión en forma SOP puede convertirse fácilmente en un diagrama lógico. El diagrama lógico que implementa la ecuación anterior es: Nótese la naturaleza de dos niveles del diagrama lógico. Cuando se asume que tanto la variable como su complemento están disponibles (como es casi siempre el caso), llamamos a éstas de doble riel. 3.1.2. Forma Normal Una ecuación SOP en la que cada producto contiene todas las variables de entrada ya sea en forma verdadera o en forma complementada, está en forma NORMAL o CANÓNICA. Una ecuación en forma normal no necesariamente es la más simple o la única ecuación para evaluar una función booleana en particular. Por ejemplo, la siguiente ecuación es equivalente a la dada anteriormente. F = AB + AB C + BC (3.2) 3.1. FORMA “SUMA DE PRODUCTOS” 17 Figura 3.1: Diagrama lógico de un SOP Observe que esta ecuación no está en forma normal. Aun cuando puedan existir varias ecuaciones para una función dada, sólo existirá una forma normal. Para convertir una ecuación a forma normal, debemos “multiplicar” los términos a los que les falte una variable por la variable faltante, ası́: F = AB(1) + AB C + (1)BC (3.3) Se sabe que X + X = 1. Por lo tanto, F = AB(C + C) + AB C + (A + A)BC (3.4) F = ABC + ABC + AB C + ABC + ABC (3.5) F = ABC + AB C + ABC + ABC (3.6) de donde, 18 CAPÍTULO 3. CIRCUITOS BÁSICOS DE 2 NIVELES 3.1.3. Mintérminos Observando la tabla 3.1 vemos que cada combinación de variables de entrada forma un valor binario entre 0 y 2N − 1 en donde N es el número de variables de entrada. Puesto que cada combinación posible de variables de entrada forma un valor binario único, una combinación de entrada puede representarse por el valor decimal equivalente al valor binario formado por las entradas. A este valor lo llamamos número mintérmino. Por ejemplo, cuál combinación de entrada representa el mintérmino 5 (m5 )? Asumiendo las tres variables de entrada usadas anteriormente: 5 decimal = 101 binario ABC Cuál combinación representa el mintérmino 2? 2 decimal = 010 binario ABC Cuál mintérmino corresponde a ABC? ABC 110 binario = 6 decimal Usando mintérminos, la ecuación 3.1 la podemos escribir como: F = m2 + m3 + m4 + m7 (3.7) Esta ecuación también la podemos representar simplificadamente como: F = 3.2 X m(2, 3, 4, 7) (3.8) FORMA “PRODUCTO DE SUMAS” Mientras que la ecuación SOP es una serie de productos conectados por suma, la ecuación POS (Productos de sumas) es una serie de sumas (OR) conectadas por la multiplicación (AND). Para formular una ecuación POS, decimos que la salida de una red digital será 1 solamente cuando no sea 0. En la tabla 3.1, la salida es igual a 0 para los mintérminos 0,1,5 y 6. Por lo tanto, F = m0 m1 m5 m6 Veamos qué significa un mintérmino complementado: m5 = ABC de donde m5 = ABC (3.9) 3.2. FORMA “PRODUCTO DE SUMAS” 19 si aplicamos el teorema de DeMorgan: m5 = (A + B + C) = (A + B + C) de esta forma podemos escribir: F = (A + B + C)(A + B + C)(A + B + C)(A + B + C) El procedimiento lo podemos resumir de la siguiente forma: La ecuación POS será el producto lógico de N términos de suma en donde N es el número de entradas en la tabla de verdad para los cuales la salida es 0. Los términos de suma se forman conectando con OR los complementos de cada variable de entrada para aquellas combinaciones cuya función de salida es 0. 3.2.1. Implementación del Circuito POS El proceso es similar al de una ecuación SOP: Figura 3.2: Diagrama lógico de un POS 3.2.2. Maxtérminos Cuando derivamos la ecuación POS, usamos los mintérminos invertidos. Un mintérmino invertido se llama maxtérmino. 20 CAPÍTULO 3. CIRCUITOS BÁSICOS DE 2 NIVELES F = m0 m1 m5 m6 Ésta ecuación la podemos escribir en forma simplificada ası́: F = 3.3 Y m(0, 1, 5, 6) (3.10) CONSIDERACIONES DE DISEÑO Aunque las implementaciones SOP se usan más frecuentemente, existen aplicaciones para las cuales es más conveniente la implementación POS. Por ejemplo, consideremos una red digital con tres entradas para la cual la salida es 1 para seis de las ocho posibles combinaciones de entrada. Expresada en forma SOP, la ecuación resultante tendrı́a 6 términos y el circuito requerirı́a seis compuertas AND y una compuerta OR de 6 entradas. Una implementación POS del mismo circuito tendrı́a solamente 2 términos y requerirı́a solo dos compuertas OR y una compuerta AND de dos entradas. . Capı́tulo 4 Simplificación de Circuitos Conceptos básicos Minimización por método algebraico Minimización por tabla de Karnaugh Condiciones No Importa Compuertas universales Implementación con compuertas universales Saber Hacer Obtener la función minimizada a partir de la ecuación canónica. Implementar la ecuación minimizada utilizando compuertas universales 21 22 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS 4.1 TÉCNICAS DE REDUCCIÓN DE EXPRESIONES Las técnicas estudiadas en el capitulo 3 redujeron los requerimientos de hardware implementando expresiones con solo un tipo de compuerta. Se pueden lograr reducciones adicionales simplificando la ecuación original antes de intentar implementarla. Esta reducción se ejecuta tı́picamente por manipulación algebraica o con los mapas de Karnaugh. 4.1.1. REDUCCIÓN ALGEBRAICA En el capı́tulo 3 convertimos una expresión a su forma normal multiplicando por las variables faltantes y sus complementos. Si pensamos en forma inversa, es decir, si removemos esas combinaciones de la ecuación en forma normal, resultará la ecuación original más simple. Esta es la base de la reducción de expresiones: remover las combinaciones de una variable y su complemento. Considere la siguiente ecuación, la cual ya está en forma simplificada: F = BC + AB (4.1) La convertimos en forma normal multiplicando por las variables faltantes y sus respectivos complementos: F = (A + A)BC + AB(C + C) F = ABC + ABC + ABC + AB C (4.2) Si se diera esta ecuación final en forma normal y se pidiese reducirla a su forma más simple, ¿cómo se harı́a? Puesto que nosotros la derivamos de la ecuación original, el proceso es obvio. Los primeros dos términos de la ecuación en forma normal fueron generados por: ABC + ABC = (A + A)BC (4.3) ABC + AB C = AB(C + C) (4.4) y los dos últimos por: puesto que la unión de cualquier variable con su complemento es 1, esta combinación se puede eliminar produciendo la ecuación original: F = BC + AB (4.5) 4.1. TÉCNICAS DE REDUCCIÓN DE EXPRESIONES 23 El proceso empleado aquı́ es sencillo. Si en dos términos una variable aparece tanto en su forma verdadera como complementada y las variables restantes son iguales, se puede eliminar la variable y su respectivo complemento y el resultado es simplemente un término compuesto de las variables restantes. Para ilustrar adicionalmente el proceso, simplifiquemos la siguiente expresión: F = A BC + ABC + ABC + ABC (4.6) En los dos primeros términos, B está presente tanto en su forma normal como complementada y las variables restantes son iguales. Por lo tanto, los primeros dos términos pueden reducirse a: A BC + ABC = A(B + B)C = AC (4.7) En los dos últimos términos, B nuevamente está presente tanto en su forma normal como complementada. Por lo tanto, ABC + ABC = A(B + B)C = AC (4.8) Produciendo una expresión reducida: F = AC + AC (4.9) Si examinamos la ecuación vemos que la podemos simplificar aún más. Puesto que A aparece tanto en su forma verdadera como complementada, podemos reducirla a: AC = AC = (A + A)C = C F = C (4.10) (4.11) Por lo tanto, el hardware necesario para implementar esta función es simplemente un cable que conecta a C con la salida F. La simplificación posible y la reducción resultante en los requerimientos de hardware son obvias. Pero la reducción algebraica es a menudo difı́cil, especialmente en expresiones complejas. La secuencia apropiada de operaciones que debe ejecutarse no siempre es clara. Pero ası́ como en el capı́tulo 3 se utilizó un método gráfico para implementar circuitos con un solo tipo de compuerta, de igual modo existe un método gráfico para facilitar la reducción de expresiones. 24 4.1.2. CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS MAPAS DE KARNAUGH Los mapas de Karnaugh son un método gráfico para reducir expresiones a su forma mı́nima. Un mapa K es una tabla de verdad organizada especialmente de tal modo que las reducciones posibles se puedan ver fácilmente. En las figuras 4-1, 4-2 y 4-3 se muestra la forma de los mapas K de dos, tres y cuatro entradas. En lugar de enunciar todas las combinaciones de las entradas como en una tabla de verdad normal, los mapas K usan las posiciones de los cuadros en el mapa para representar las diferentes combinaciones de entrada: @B 0 A @@ 1 0 0 1 3 2 1 Figura 4.1: Mapa K de 2 entradas @ BC 00 A @@ 01 11 10 0 0 1 3 2 4 5 7 6 1 Figura 4.2: Mapa K de 3 entradas @ CD 00 AB@@ 01 11 10 00 0 1 3 2 4 5 7 6 12 13 15 14 8 9 11 10 01 11 10 Figura 4.3: Mapa K de 4 entradas Para ayudar en la determinación de cuál combinación de entrada está representada en un cuadro, las filas y las columnas están marcadas con la combinación parcial de entrada representada por la fila y la columna. Por ejemplo, cuál combinación de entrada 4.1. TÉCNICAS DE REDUCCIÓN DE EXPRESIONES 25 está representada por el cuadro en la fila 2, columna 4 del mapa K de 4 entradas? La fila 2 está marcada 01; la columna 4 está marcada 10. Colocando estos dos valores uno junto al otro en orden fila-columna, se produce 0110, el cual es el mintérmino 6 o AB CD . El cuadrado en la fila 3 columna 2 representa 1101, el cual es el mintérmino 13 o ABCD. Observando más profundamente vemos que la etiqueta 00 en la fila 1 indica que A y B son ambos 0 para toda la fila. De igual forma, la etiqueta 10 en la columna 4 indica que C es 1 y D es 0 para toda la columna. Para representar una función con un mapa K, los unos y los ceros se colocan en los cuadrados apropiados de acuerdo con la combinación de entradas representada por cada cuadro. El arreglo especial del mapa K asegura que las combinaciones de entrada representadas por dos cuadrados adyacentes son idénticas excepto que una variable aparece en su forma verdadera en un cuadrado y en su forma complementada en el otro. Nótese que éste es simplemente el criterio especificado en la sección 4.1.1 para la reducción de dos términos. Por lo tanto, dos cuadrados adyacentes pueden ser elegibles para ser reducidos. Esta relación puede verse mirando dos cuadros adyacentes en un mapa K. Por ejemplo, considere los dos primeros cuadrados de la fila 1 de un mapa K de 4 entradas. El primer cuadrado representa la combinación de entrada 0000, o A B C D . El segundo cuadrado representa la combinación de entrada 0001, o A B CD. Entre estos dos términos, todo es idéntico excepto que D aparece en su forma verdadera en el segundo cuadro y en su forma complementada en el primer cuadro. Nótese que esta relación se mantiene entre dos cuadrados adyacentes cualquiera, tomados ya sea horizontal o verticalmente. Además, la relación se mantiene entre los lados exteriores (es decir, fila 1, cuadro 1 y 4 o columna 1, filas 1 y 4, etc.); por lo tanto, los lados extremos son considerados adyacentes. Uso de los mapas de KARNAUGH Para usar un mapa K en la reducción, primero llene el mapa K con la salida de la función. La tabla de verdad normal para la ecuación 4.2 se muestra en la figura 4.4, en donde también se ha diligenciado el mapa K. A 0 0 0 0 1 1 1 1 B 0 0 1 1 0 0 1 1 C 0 1 0 1 0 1 0 1 F 0 0 0 1 1 1 0 1 @ BC 00 A @@ 0 01 0 0 1 0 1 1 4 Figura 4.4: 11 1 3 1 5 10 0 2 1 7 0 6 26 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS Puesto que los cuadrados adyacentes representan términos que pueden ser reducidos, busque y encierre grupos de los unos adyacentes. Un grupo debe constar de 1,2,4,8 ó 16 unos, es decir, una potencia de 2. En general, entre mayor sea el grupo encerrado, más sencilla será la expresión reducida. Por lo tanto, primero busque grupos de 16 (no aplicable en este ejemplo, por supuesto) y luego siga buscando grupos de 8, de 4, de 2 y finalmente, los unos aislados, hasta que los haya agrupado a todos. Este proceso se muestra en la figura 4.5 @ BC 00 A @@ 0 01 0 0 0 1 11 10 1 4 1 0 3 1 1 5 2 1 0 7 6 Figura 4.5: La expresión resultante SOP constará de un término por cada grupo encerrado. Por lo tanto, entre menos grupos encerrados, más simple será la expresión. En el mapa K de la figura 4.5, obtuvimos 2 grupos. El producto resultante para cada grupo estará compuesto de aquellas variables que son iguales para todo el grupo. Por ejemplo, para el grupo vertical, tanto B como C son 1 para todo el grupo; por lo tanto, el término producto resultante es BC. En el grupo horizontal, A es 1 en ambos cuadros y B es 0 en ambos cuadros. Por consiguiente, el producto resultante será AB. Combinando ambos resultados obtendremos: F = AC + AB (4.12) Como segundo ejemplo, reduzcamos la ecuación 4.6 usando mapas K. En la figura 4.6 aparece la tabla de verdad normal y el mapa K resultante. @ BC 00 A @@ 0 01 0 0 1 1 1 0 4 11 ' 1 3 1 10 $ 0 2 1 5 7 & 0 6 % Figura 4.6: Si se buscan inicialmente grupos de 8, no encontramos ninguno; si se buscan grupos de 4, encontraremos uno de acuerdo con la figura 4.6. 4.1. TÉCNICAS DE REDUCCIÓN DE EXPRESIONES 27 Puesto que ya hemos encerrado todos los unos, no es necesario seguir buscando más grupos. La ecuación resultante SOP tendrá solamente un término, en el cual aparecen sólo aquellas variables que no cambian para todo el grupo. Vemos que solamente C es igual a 1 para los cuatro cuadros. Por lo tanto, la expresión final reducida es: F =C (4.13) Como ejemplo final, miremos un caso más complejo. En la figura 4.7 tenemos la tabla de verdad y el mapa K para un circuito de 4 entradas. @ CD 00 AB@@ 00 0 0 01 11 1 1 0 0 0 1 7 0 1 6 0 1 13 15 14 % & 0 8 10 5 12 10 11 1 3 2 $ ' 1 4 01 1 9 0 11 0 10 Figura 4.7: La figura 4.7 ilustra cómo reducir ésta función. Según se ve, puede formarse un grupo de 4 partiendo del hecho de que los vértices extremos son considerados adyacentes. Nótese una segunda aplicación del enrollamiento al formar el grupo de los unos entre las filas superior e inferior. Finalmente, nótese el grupo de dos unos, uno usando un 1 que ya habı́a sido utilizado. El resultado constará de 3 términos puesto que tenemos tres grupos encerrados. Mirando el primer grupo de 4, vemos que B y D permanecen constantes. Para el grupo vertical de 2, B es 0, C es 0 y D es 1. En el grupo final de 2, A es 0, B es 1 y C es 1. Por lo tanto, el resultado es: F = BD + B CD + ABC (4.14) Condiciones “No Importa” Muchas funciones tienen varias combinaciones de entrada para las cuales no se define ninguna salida. Estas se denominan condiciones “no importa”. En un mapa K, una condición “no importa” puede usarse como 0 o como 1, lo cual resulta en una expresión más simple. 28 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS Tomemos como ejemplo la red definida por la tabla de verdad que se muestra en la tabla 4.1. Esta red toma un dı́gito BCD de 4 bits como entrada. La salida es 1 si el dı́gito es mayor que 5; de otra forma, la salida es 0. Puesto que es BCD, las entradas válidas corresponden a los dı́gitos decimales entre 0 y 9; por lo tanto, los mintérminos 10 a 15 son considerados como condiciones “no importa” y los marcamos con una X. A 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 B 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 C 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 D 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 F 0 0 0 0 0 0 1 1 1 1 X X X X X X Cuadro 4.1: El mapa K para esta tabla lo vemos en la figura 4.8 @ CD 00 AB@@ 00 01 0 0 01 0 1 0 4 11 0 X 10 1 X 1 8 1 6 X 15 1 9 0 2 7 13 10 0 3 5 12 11 X 14 X 11 X 10 Figura 4.8: Observemos que en la figura se han encerrado dos grupos, para los cuales la expresión resultante es: 4.2. IMPLEMENTACIÓN CON UN TIPO DE COMPUERTA F =AB C +AB C 29 (4.15) Puesto que las X las podemos tomar como 0. Ası́ como el 1, podemos formar grupos según se muestra en la figura 4.9 @ CD 00 AB@@ 00 01 0 0 01 10 0 0 3 2 ' 0 0 X 12 10 0 1 4 5 ' 11 11 X 13 1 1 7 1 $ 6 X X 15 14 & 1 8 9 & X 11 $ X 10 % % Figura 4.9: Ahora tenemos un grupo de 8 y un grupo de 4. La única variable común a todos los términos del grupo de 8 es A; las variables comunes al grupo de 4 son B y C. Por lo tanto, la expresión resultante es: F = A + BC (4.16) El uso de condiciones “no importa” tı́picamente nos permite la reducción adicional tal como se ha demostrado. 4.2 IMPLEMENTACIÓN CON UN TIPO DE COMPUERTA 4.2.1. MOTIVACIÓN En la industria, el costo es tı́picamente el factor de mérito en el diseño y la producción de bienes. En la producción de circuitos digitales, aun cuando pueda parecer que el departamento de compras es el responsable de reducir los costos buscando el proveedor más barato, los ingenieros que diseñan los circuitos digitales tienen varios métodos a su disposición para reducir el costo del diseño. En general, entre más pocas y más baratas sean las partes requeridas para construir un circuito, menor será el costo. Por lo tanto, un objetivo importante en el diseño de un circuito, es minimizar el número de elementos y su costo asociado. 30 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS Para ilustrar lo anterior, nos remitimos al capı́tulo dos en el cual se introdujeron algunas ideas para convertir una expresión POS a SOP en un diagrama lógico. Por ejemplo, dada la siguiente expresión SOP: F = AB + CD (4.17) La implementación de este circuito requiere dos compuertas AND y una compuerta OR. Los chips requeridos son el 7408 (cuatro ANDs) y el 7432 (cuatro ORs). La implementación de las expresión dada utiliza sólo dos de los cuatro compuertas AND y sólo una de las cuatro compuertas OR. En la producción, este tipo de ineficiencia serı́a muy costosa. Para obviar la ineficiencia, se acostumbra implementar una expresión que use solamente un tipo de compuerta, compuertas NAND o NOR. La compuerta NAND es la función cuya implementación es más “natural” a nivel interno del chip. Esta cualidad hace que la compuerta NAND sea la más rápida y la más barata de los chips TTL. Además, las compuertas NAND y NOR pueden actuar como inversores, eliminando la necesidad de chips inversores separados. ¿Cómo puede realizarse una expresión en términos de AND y OR utilizando solamente compuertas NAND o NOR? Existen dos métodos primarios para realizar esto. Primero, usando el algebra booleana. La expresión original puede ser manipulada y convertida en una expresión equivalente que utilice el tipo de compuerta deseada. Este método puede volverse extremadamente complicado, especialmente cuando se trata de expresiones extensas. El segundo método utiliza reglas de equivalencia de compuertas, las cuales permiten que cualquier compuerta desempeñe las funciones AND y OR. 4.2.2. MANIPULACIÓN ALGEBRAICA Las leyes del álgebra booleana nos permiten convertir una expresión booleana en una expresión equivalente que sea directamente implementable con el tipo de compuerta deseada. Por ejemplo, consideremos la implementación de la ecuación 4.17 utilizando solamente compuertas NAND. La función de la compuerta NAND sobre dos entradas, A y B, se representa como: F = AB (4.18) Por lo tanto, para implementar una expresión usando sólo compuertas NAND, el objetivo es reducir todas las operaciones lógicas a la forma anterior, es decir, a la de una compuesta NAND. 4.2. IMPLEMENTACIÓN CON UN TIPO DE COMPUERTA 31 De nuestra expresión original: F = AB + CD (4.19) aplicamos doble inversión y el teorema de DeMorgan F = AB + CD (4.20) F = (AB).(CD) (4.21) examinado esta expresión encontramos tres formas NAND: 1. (AB) 2. (CD) 3. XY en donde X y Y corresponden a las expresiones 1 y 2. Por lo tanto, la expresión puede realizarse como sigue: Figura 4.10: ´?Cómo se puede implementar la ecuación 4.17 usando compuertas NOR? Recordemos que la función NOR sobre dos entradas es: F =A+B (4.22) F = AB + CD (4.23) si tomamos la ecuación original, si invertimos dos veces y aplicamos DeMorgan: 32 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS F = AB + CD (4.24) F = (A + B) + (C + D) (4.25) en esta expresión encontramos dos formas NOR: 1. (A + B) 2. (C + D) Finalmente, la función lógica final entre 1 y 2 es la función OR, la cual se puede obtener invirtiendo la salida de la NOR Figura 4.11: Como puede observarse, este método puede llegar s ser muy complejo y en consecuencia, la probabilidad de error es alta. 4.2.3. EQUIVALENCIAS DE COMPUERTAS El álgebra booleana se compone solamente de tres operadores: AND, OR y NOT. Cualquier expresión puede implementarse usando las combinaciones de estas tres funciones. Para implementar un circuito con un solo tipo de compuerta se deben ejecutar tres operaciones de algún modo. Ejecutando la función NOT con NAND y NOR NAND y NOR pueden funcionar como inversores uniendo las entradas Ejecutando la función AND con NAND y NOR Por medio de las transformaciones booleanas podemos determinar cómo ejecutar la función AND con compuertas NAND o NOR. 4.2. IMPLEMENTACIÓN CON UN TIPO DE COMPUERTA 33 Figura 4.12: La función AND sobre dos entradas se ilustra en el algebra booleana como: F = AB (4.26) La función NAND se expresa como: G = AB F =G (4.27) Esta ecuación puede reducirse a la función AND complementando la ecuación para remover el NOT. Por lo tanto, la compuerta NAND ejecutará la función AND si invertimos la salida. La función NOR sobre dos entradas es: F =A+B (4.28) si aplicamos el teorema de DeMorgan, obtenemos F =AB A=C B=D (4.29) En resumen, una compuerta NAND ejecutará la función AND si invertimos la salida. Una compuerta NOR ejecutará la función AND si invertimos las entradas. Ejecutando la función OR con NAND y NOR La función OR sobre dos entradas la representamos como F =A+B (4.30) F = CD (4.31) La función NAND se expresa como 34 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS si aplicamos el teorema de DeMorgan: F =CD A=C B=D (4.32) Por lo tanto, una compuerta NAND ejecuta la función OR si se complementan las variables de entrada. La función NOR sobre dos entradas es: G=A+B F =G (4.33) La cual puede reducirse a la función OR complementando toda la ecuación. Por lo tanto, la compuerta NOR ejecuta la función OR si se complementa la salida. Definiciones simbólicas Para clarificar la doble naturaleza de las compuertas, se puede representar simbólicamente, de dos formas. En las figuras 4.13 y 4.14 se muestran dos representaciones de la compuerta NAND y dos representaciones de la compuerta NOR, respectivamente. Notamos que la presencia de un cı́rculo a la entrada indica que la entrada debe ser invertida para ejecutar apropiadamente la función dictada por la forma del sı́mbolo, es decir, la función AND y OR. Además, la presencia de un cı́rculo a la salida indica que ésta debe invertirse para ejecutar apropiadamente la función dictada por la forma del sı́mbolo. Figura 4.13: Representaciones de la compuerta NAND Figura 4.14: Representaciones de la compuerta NOR 4.2. IMPLEMENTACIÓN CON UN TIPO DE COMPUERTA 35 Entradas y Salidas activo alto y activo bajo Para definir aún más el significado de los cı́rculos en los sı́mbolos de las compuertas, podemos decir que una compuerta con un cı́rculo a la salida tiene una salida ACTIVA BAJA. Una compuerta con cı́rculos en la entrada tiene entradas ACTIVAS BAJAS. De igual manera, una compuerta sin cı́rculo a la salida tiene salida ACTIVA ALTA y una compuerta sin cı́rculos a la entrada tiene entradas ACTIVAS ALTAS. Por ejemplo, la forma AND de la compuerta NAND se puede pensar como una compuerta AND con entradas activas altas y la salida activa baja. La forma OR de la compuerta NAND se puede pensar como una compuerta OR con entradas activas bajas y la salida activa alta.oo El término activo alto se refiere a niveles lógicos como los que hemos mencionado hasta ahora: un verdadero se representa por un nivel lógico alto. Activo bajo indica que un verdadero es representado por un nivel lógico bajo en lugar de un nivel lógico alto. Para ilustrar esto, consideremos la ejecución de la función AND con la compuerta NAND. La función AND produce una salida verdadera solamente cuando todas las entradas son verdaderas. Si miramos la forma AND de la compuerta NAND, vemos que también ejecuta la función AND pero como tiene una salida activa baja, el valor verdadero será indicado por un nivel lógico bajo en lugar de un nivel lógico alto. Por lo tanto, para ver una salida activa alta normal, debemos invertir la salida de una compuerta NAND. 4.2.4. DISEÑO DE DIAGRAMAS LÓGICOS QUE UTILIZAN EQUIVALENCIAS DE COMPUERTAS Teniendo en mente el concepto de equivalencias de compuertas, veremos a continuación el diseño de diagramas lógicos. Según las guı́as del capı́tulo ??, el diagrama lógico para implementar la ecuación 4.17 es como sigue: Figura 4.15: 36 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS Diseño de diagramas que utilizan compuertas NAND Este diagrama se convierte sólo a compuertas NAND reemplazando inicialmente todas las compuertas OR con la forma OR de la compuerta NAND y posteriormente, todas las compuertas AND con la forma AND de la compuerta NAND. No dibujar todavı́a ninguna conexión. Figura 4.16: Puesto que tratamos con entradas y salidas activas altas en el mundo real, las entradas iniciales y salidas finales generalmente deben ser activas altas. Si miramos la figura 4.16 vemos que esta condición ya está satisfecha. La siguiente etapa consiste en conectar los sı́mbolos AND y OR. Puesto que la forma OR de la compuerta NAND requiere entradas activas bajas y que la salida de la forma AND ya es activa baja, no se necesita conversión de nivel y puede hacerse la conexión directa entre las salidas de las formas AND y las entradas de la forma OR. En general, puede hacerse una conexión directa entre una salida y una entrada, ambas activas bajas, o entre una salida y una entrada, ambas activas altas. Si una es activa baja y la otra es activa alta, debemos utilizar un inversor. Haciendo las conexiones como se ha descrito, el diagrama lógico final es como sigue: Figura 4.17: Nótese que al usar las formas AND y OR de las compuertas NAND, es mas obvia la función del circuito. Mirando la figura 4.17, vemos rápidamente que es una implementación SOP, mientras que si vemos el circuito equivalente de la figura 4.10, encontramos que la función real del circuito no es clara. 4.2. IMPLEMENTACIÓN CON UN TIPO DE COMPUERTA 37 El segundo ejemplo muestra un caso en el que se necesita una conversión de nivel. Tomemos la implementación de una compuerta OR de tres entradas usando solamente compuertas NAND de dos entradas. Si se dispone de compuertas OR de dos entradas, esta función se podrı́a implementar como sigue: Figura 4.18: Para implementar solamente con compuertas NAND de dos entradas, procedemos como antes reemplazando las compuertas OR con la forma OR de la compuerta NAND, ası́: Figura 4.19: Para completar el diagrama debemos asegurarnos que hay entradas y salidas activas altas. Puesto que las entradas de las formas OR son activas bajas, debemos invertir las variables de entrada. Si suponemos entradas de doble riel, no mostramos los inversores de entrada. La salida final del circuito ya es activa alta, por lo cual no necesitamos conversión. La conversión final se realiza entre la primera y la segunda formas OR, en donde vemos que es necesario un inversor. Figura 4.20: 38 CAPÍTULO 4. SIMPLIFICACIÓN DE CIRCUITOS DISEÑO DE DIAGRAMAS LÓGICOS QUE UTILIZAN COMPUERTAS NOR Al igual que con las compuertas NAND, el primer paso para implementarlas usando solamente compuertas NOR, es reemplazar todas las compuertas OR con la forma OR de la compuerta NOR y todas las compuertas AND con la forma AND de la compuerta NOR. Con la figura 4.14 obtendremos: Figura 4.21: Si hacemos las mismas consideraciones de niveles activos alto y activos bajos, finalmente obtendremos: Figura 4.22: . Capı́tulo 5 Aplicaciones Combinacionales Conceptos básicos Multiplexores Demultiplexores Sumadores Codificadores Comparadores Convertidores de Código Circuitos MSI Saber Hacer Conocer y saber utilizar las aplicaciones más importantes de tipo combinacional, tales como mux, demux, sumador, comparador, convertidores de código. 39 40 5.1 CAPÍTULO 5. APLICACIONES COMBINACIONALES MULTIPLEXORES Y DEMULTIPLEXORES 5.1.1. Definición Nuestro estudio previo de las bases de la lógica digital y de diseño de circuitos, nos permitió entender y diseñar algunos circuitos importantes. En este capı́tulo estudiaremos dos de esos circuitos: el multiplexor y el demultiplexor. El multiplexor (mux) efectúa la función de un conmutador rotatorio, seleccionando una de varias entradas para conectar a una sola salida; por lo general, al multiplexor se le denomina selector. El demultiplexor (demux) realiza la función inversa, es decir, conecta una sola entrada a una de varias salidas. Al demultiplexor frecuentemente se le denomina decodificador. Estas dos funciones se usan intensamente en redes digitales. La combinación mux-demux se utiliza para la comunicación serial con el fin de reducir el número de cables requeridos para pasar los datos. Esta pareja puede ser usada de manera similar para manejar despliegues de dı́gitos múltiples tales como los que se encuentran en las calculadoras. Los mux se usan frecuentemente en los circuitos digitales para controlar el enrutamiento de los datos y las señales. Por ejemplo, se puede usar un multiplexor para seleccionar la entrada a un registro particular de varias fuentes. Los decodificadores son usados para efectuar decodificaciones de direcciones de memoria. Basados en ciertas lı́neas de dirección, el decodificador puede suministrar las señales de habilitación a los chips de memoria apropiados. Además, tanto los mux como los demux pueden utilizarse para evaluar expresiones booleanas sencillas usando menos hardware que si se usaran compuertas individuales. Existen muchas aplicaciones adicionales; las descritas, simplemente empiezan a ilustrar la flexibilidad de estas dos funciones. 5.1.2. El Multiplexor Como se mencionó previamente, un mux actúa como un conmutador rotatorio conectando una de varias entradas a una salida única. La selección de cuál entrada debe ser conectada a la salida, es determinada por medio de entradas adicionales llamadas lı́neas de control o de selección. La entrada seleccionada es determinada por el equivalente binario del valor colocado en las lı́neas de selección. Por ejemplo, consideremos un mux que selecciona una de cuatro entradas para conectar a la salida. A esto lo llamamos mux de 4 a 1. Para seleccionar una de cuatro entradas, deben existir cuatro combinaciones únicas de las lı́neas de selección. Para esto se necesitan dos lı́neas de selección que nos dan las cuatro combinaciones únicas 00, 01, 10 y 11. La combinación 00 seleccionará la lı́nea 0, la combinación 01 selecciona la lı́nea 1 y ası́ sucesivamente. Esta función de multiplexor se ilustra en la tabla 5.1. Esta tabla muestra la salida F como una función de las entradas de las lı́neas de selección. En lugar de enunciar los posibles estados de la entradas de datos, ésta forma simplificada de tabla de verdad muestra la salida como función de los datos de la lı́nea de entrada O 5.1. MULTIPLEXORES Y DEMULTIPLEXORES S2 0 0 1 1 S1 0 1 0 1 41 F D0 D1 D2 D3 Cuadro 5.1: Tabla de verdad de un mux de 4 a 1 (DO ) o lı́nea de entrada 1 (D1 ) y ası́ sucesivamente. Lo anterior se implementa con la siguiente expresión: F = S2 S1 D0 + S2 S1 D1 + S2 S1 D2 + S2 S1 D3 (5.1) En la figura 5.1 se muestra una implementación con compuertas NAND del multiplexor 4 a 1. Puesto que la función mux es tan útil, existen muchos chips TTL que efectúan la operación equivalente del circuito mostrado en la figura 5.1. Por ejemplo, el 74153 contiene dos multiplexores 4 a 1, el 74151 contiene un multiplexor 8 a 1 y el 74157 contiene 4 multiplexores 2 a 1. Figura 5.1: Circuito lógico de un MUX 4 a 1. El multiplexor generalmente aparece en un circuito como una unidad funcional sencilla, no como las compuertas que conforman el circuito. La figura 5.2 muestra una representación tı́pica. 42 CAPÍTULO 5. APLICACIONES COMBINACIONALES Figura 5.2: Representación simplificada de un MUX 4 a 1 5.1.3. El Demultiplexor El demultiplexor conecta una entrada a una de varias salidas. La salida se escoge por medio de las lı́neas de selección tal como en el mux. El uso más común del demultiplexor es el de decodificador. De hecho, los demux son conocidos como decodificadores. Un decodificador coloca en 0 la lı́nea de salida definida por las lı́neas de selección. Esta función se implementa fácilmente con el demux conectando la lı́nea de entrada con 0. Para ilustrar lo anterior, consideremos la operación de un demux que conecta una entrada a una de cuatro salidas, llamado demultiplexor de 1 a 4. El demux es llamado decodificador de 2 a 4 puesto que dos lı́neas seleccionan una de cuatro salidas. La operación de este demux se ilustra en la tabla 5.2 DI 0 0 0 0 1 S2 0 0 1 1 X S1 0 1 0 1 X F0 0 1 1 1 1 F1 1 0 1 1 1 F2 1 1 0 1 1 F3 1 1 1 0 1 Cuadro 5.2: Nótese que el valor por omisión de las salidas es 1. Por lo tanto, cualquier salida no seleccionada será 1. Entonces, como lo ilustra la tabla 5.2, cuando el dato en DI sea 1, todas las salidas serán 1 sin importar la combinación de las lı́neas de selección. El decodificador coloca en 0 la lı́nea de salida seleccionada por las lı́neas de selección. Según se aprecia en la tabla 5.2, esto se logra conectando a 0 la entrada de datos. Por lo tanto, ésta puede verse como una habilitación activa baja para el decodificador. Si esta señal de habilitación no es baja, el decodificador no funcionará (todas las salidas serán 1); a menudo, los decodificadores tienen más de una lı́nea de habilitación, haciéndose necesario que todas la lı́neas de habilitación estén activadas para que funcione el decodificador. 5.1. MULTIPLEXORES Y DEMULTIPLEXORES 43 Las funciones ilustradas en la tabla 5.2 se pueden expresar algebraicamente como: F0 = Di S2 S1 (5.2) F1 = Di S2 S1 (5.3) F2 = Di S2 S1 (5.4) F3 = Di S2 S1 (5.5) En la figura 5.3 se muestra una implementación con compuertas NAND del demux 1 a 4 (decodificador 2 a 4) De igual modo que los multiplexores, el circuito demultiplexor está disponible en diferentes variaciones de chips TTL. Por ejemplo, el 74138 contiene dos demux 1 a 4 (decodificador 3 a 8) y el 74139 contiene dos demux 1 a 4 (decodificadores 2 a 4). Figura 5.3: Circuito Lógico del DEMUX 1 a 4. También los demux se colocan en los circuitos como unidades funcionales separadas. En la figura 5.4 se muestran las representaciones caracterı́sticas: Nótese la presencia de los indicadores activos bajos en la entrada de habilitación y en cada una de las salidas de la representación como decodificador. Esto indica que el 44 CAPÍTULO 5. APLICACIONES COMBINACIONALES Figura 5.4: Representación simplificada del DEMUX 1 a 4. decodificador se habilita con una entrada baja y que la salida adquiere el valor bajo al seleccionarla. 5.1.4. Aplicaciones de los Multiplexores y de los Demultiplexores Ahora que ya entendemos la operación básica del mux y el demux, miraremos en detalle las aplicaciones mencionadas en la sección 5.1.4. Comunicación Consideremos la situación en la cual dos computadores de 16 bits deben comunicarse. La comunicación podrı́a efectuarse fácilmente utilizando la transmisión paralela de todos los 16 bits. Esto requerirı́a al menos 18 conductores, uno por cada bit; además, uno para referencia de tierra, y adicionalmente una señal de indicación de que los datos están disponibles. Un método alterno se muestra en la figura 5.5. Utilizando un multiplexor para seleccionar un bit de la palabra de entrada y un demultiplexor para conectar el dato al bit apropiado de la palabra de salida, se puede establecer una comunicación serial usando solamente 6 lı́neas: una para la lı́nea de datos, cuatro lı́neas de selección y la lı́nea de tierra. Se puede transmitir una palabra completa variando secuencialmente las lı́neas de selección desde 0 hasta 15. Esta técnica se conoce con el nombre de MULTIPLEXACIÓN. Aunque se requieren menos conductores al usar la multiplexación, el método de transferencia paralelo es inherentemente capaz de lograr velocidades de transmisión mayores. Pero en muchas aplicaciones, la velocidad que se puede obtener con el multiplexado es suficiente y en consecuencia, constituye es una ventaja la reducción de las conexiones. 5.1. MULTIPLEXORES Y DEMULTIPLEXORES 45 Figura 5.5: Comunicación usando MUX-DEMUX. Enrutamiento de datos En un computador tı́pico, el contador de programa (CP ) debe ser cargado desde fuentes diferentes. Por ejemplo, cuando se tiene la ejecución en lı́nea recta, el CP simplemente debe incrementarse después de cada instrucción. En este caso, el CP debe ser cargado desde un contador. Si se ejecuta una instrucción de salto absoluto, el CP se cargará con la dirección especificada en la instrucción, la cual normalmente estará en el registro de instrucción RI. Si se ejecuta una instrucción de salto relativo, entonces el desplazamiento especificado debe sumarse al valor corriente de CP . En este otro caso el CP se cargará con la salida de la unidad aritmética lógica U AL. Un mux es ideal para este tipo de situación: seleccionar una de varias entradas. En esta situación, el CP se conecta a la salida del mux y las entradas con el contador, con el registro de instrucción y con la U AL, tal como ya se describió. Colocando diferentes valores en las lı́neas de selección, puede escogerse la entrada al CP desde diferentes fuentes. El valor colocado en las lı́neas de selección proviene de un campo, una microinstrucción o de un secuenciador fijo, que controla la ejecución de las instrucciones. Existe un problema obvio con este enfoque. Suponga que el computador con el cual se está trabajando, utiliza direcciones de 16 bits. El mux que se necesita debe tener entradas de 16 bits cada una pero un mux solo tiene una entrada y no 16. La solución es utilizar un mux por cada bit de la palabra como se ilustra en la Figura 5.6 donde CO se refiere al bit 0 del contador, R0 se refiere al bit 0 de la dirección en el registro de instrucción, U AL0 se refiere al bit 0 de la salida de la U AL y ası́ sucesivamente para los 15 bits restantes. Las mismas lı́neas de selección van a todos los multiplexores. 46 CAPÍTULO 5. APLICACIONES COMBINACIONALES Figura 5.6: Enrutamiento de datos. Decodificación de Direcciones Consideremos un sistema simple con microprocesador que tenga una memoria de 256 bytes. Suponga que esta memoria está hecha con un chip de RAM de 256X8 (256 registros de 8 bits). Para identificar las posiciones de este chip se requieren 8 lı́neas de dirección (direcciones 00-FF). Esta configuración se muestra en la figura 5.7. Nótese que el chip de RAM tiene una entrada de habilitación activa baja. La RAM se habilita en este caso colocando una señal baja en la lı́nea de habilitación. Para no complicar el diagrama, no se han incluido las ocho lı́neas de datos. Figura 5.7: Chip de RAM de 256 x 8. Ahora queremos incrementar la memoria del computador a 1K. Esto requiere obviamente cuatro chips de RAM 256 x 8. El direccionamiento de estos chips puede dividirse como sigue: Dirección 0000-00FF 0100-01FF 0200-02FF 0300-03FF Chip 0 1 2 3 Las 8 lı́neas de dirección más bajas (A7 -A0 ) irán a las lı́neas de dirección de cada uno de los cuatro chips para seleccionar una de las 256 posiciones de cada chip. Las siguientes dos lı́neas de la dirección (A8 y A9 ) determinan cuál de los cuatro chips debe utilizarse. 5.1. MULTIPLEXORES Y DEMULTIPLEXORES 47 Cuando A8 y A9 son ambas 0, debe habilitarse el chip 0. Cuando A9 sea 0 y A8 sea 1, debe habilitarse el chip 1 y ası́ sucesivamente. Si se usan las lı́neas A9 y A8 como entradas de selección de un decodificador de 2 a 4, una de las cuatro salidas se vuelve baja basada en las dos lı́neas de dirección. Esta salida se conecta a la entrada de habilitación del chip RAM. La disposición descrita se ve en la Figura 5.8. Figura 5.8: Memoria RAM de 1K. Implementación de las expresiones con multiplexores Un multiplexor se puede usar para implementar fácilmente una tabla de verdad sin necesidad de circuitos complejos AND-OR. Consideremos la tabla de verdad 5.3 A 0 0 0 0 1 1 1 1 B 0 0 1 1 0 0 1 1 C 0 1 0 1 0 1 0 1 F 1 1 0 1 1 0 0 0 Cuadro 5.3: Una red digital que implemente esta tabla de verdad debe tener una salida 1 para el mintérmino 0, una salida 1 para el mintérmino 1, una salida 0 para el mintérmino 2 y ası́ sucesivamente. Si se usa A,B y C como entradas a las lı́neas de selección de un multiplexor de 8 a 1, la salida del multiplexor es la entrada 0 (I0 ) para el mintérmino 0, la entrada 1 (I1 ) para el mintérmino 1 y ası́ sucesivamente. Por lo tanto, el multiplexor 48 CAPÍTULO 5. APLICACIONES COMBINACIONALES puede usarse para implementar la tabla de verdad simplemente conectando las entradas de la función a las lı́neas de selección y conectando las entradas del multiplexor a 1 o a 0 de acuerdo con la salida para ese mintérmino. En la figura 5.9 se muestra el circuito respectivo. Figura 5.9: Implementación de una expresión con un MUX En el ejemplo anterior, implementamos una tabla de verdad de 8 entradas con un mux 8 a 1. Esta función también puede construirse con un mux 4 a 1. En general, una tabla de verdad de N entradas puede implementarse ya sea con un mux de N a 1 o con un mux de N/2 a 1. Para utilizar un mux de 4 a 1, las entradas de la función A y B se conectan a las lı́neas de selección del mux. Si miramos la tabla de verdad 5.4, las conexiones requeridas serán más obvias. A 0 0 0 0 1 1 1 1 B 0 0 1 1 0 0 1 1 C 0 1 0 1 0 1 0 1 F 1 1 0 1 1 0 0 0 Cuadro 5.4: Para AB = 00, la salida de la función es siempre 1; por lo tanto, la entrada 0 (I0 ) del mux se conecta a 1. Si AB = 01, la salida de la función es 0 cuando C es 0 y 1 cuando C es 1. Por lo tanto, se conecta C a la entrada 1 (Y1 ) del mux. Si AB = 10, la salida de la función es 1 cuando C es 0 y 0 cuando C es 1. Por lo tanto, conectamos Cá la entrada 2 (I2 ) del mux. Si AB = 11, la salida de la función es siempre 0. Por consiguiente, conectamos la entrada 3 (I3 ) a 0. Esta implementación se muestra en la figura 5.10. 5.2. SUMADORES BINARIOS Y OTROS CIRCUITOS COMBINACIONALES 49 Figura 5.10: Implementación de una expresión con un MUX Implementación de expresiones con decodificadores Las tablas de verdad también se pueden implementar con decodificadores. Un de estos decodificadores colocará en 0 la salida escogida mediante las lı́neas de selección. Consideremos un decodificador de 3 a 8 y una tabla de verdad de 3 variables. Si se colocan las entradas a la tabla de verdad en las lı́neas de selección del decodificador, las salidas seleccionadas por las entradas a la tabla de verdad se ubicarán en cero. Por ejemplo, la salida de la función definida en la tabla 5.3 es 1 para los mintérminos 0, 1, 3 y 4. Si alguno de estos mintérminos se aplica a las lı́neas de selección del decodificador, esa salida tomará el valor bajo. Si alguna de esas salidas toma el valor bajo, la salida del circuito debe ser 1. Por lo tanto, debemos usar la función OR de las salidas 0, 1, 3 y 4. El decodificador suministra salidas activas bajas, utilizando la forma OR de la compuerta NAND puesto que tiene entradas activas bajas. La implementación se muestra en la figura 5.11. 5.2 SUMADORES BINARIOS Y OTROS CIRCUITOS COMBINACIONALES 5.2.1. Sumadores Binarios Los sumadores juegan un papel importante en los circuitos digitales, especialmente en los computadores. Los sumadores usados en circuitos digitales son tı́picamente sumadores binarios. Los valores binarios de dı́gitos múltiples son sumados 1 bit cada vez, produciendo cada posición un dı́gito de suma y un acarreo (Cout ) hacia la siguiente posición. El proceso es análogo al procedimiento que se usa en aritmética para sumar decimales de varios dı́gitos. 50 CAPÍTULO 5. APLICACIONES COMBINACIONALES Figura 5.11: Implementación de una expresión con un DEMUX. Sumadores medios y sumadores completos La tabla de la suma para dos dı́gitos binarios se muestra en la tabla 5.5. Esta tabla señala tanto la suma como el acarreo producidos por la adición de 2 bits. A 0 0 1 1 B 0 1 0 1 Suma 0 1 1 0 Acarreo 0 0 0 1 Cuadro 5.5: Nótese que la suma es simplemente la función OR exclusivo y el acarreo es únicamente la función AND. Pero el sumador definido en la tabla 5.5 tiene un problema puesto que la posición previa puede producir un acarreo; el sumador realmente necesita 3 entradas. Un sumador sin la entrada de acarreo se denomina sumador medio. Un sumador que considera la entrada de acarreo (Cin ) se denomina sumador completo. En la tabla 5.6 se encuentra la tabla de verdad para el sumador completo. Un circuito que implementa un sumador completo se diseña fácilmente con las técnicas cubiertas hasta ahora. En la figura 5.12 se muestran las ecuaciones reducidas para las salidas de suma y acarreo y los mapas K utilizados para derivar las ecuaciones. En estos mapas, la entrada de acarreo se ha abreviado como C. Un vistazo más cercano a la tabla de verdad y a éstas expresiones revela que la función suma es verdadera cuando hay un número impar de unos a la entrada y la función acarreo 5.2. SUMADORES BINARIOS Y OTROS CIRCUITOS COMBINACIONALES Ci n 0 0 0 0 1 1 1 1 A 0 0 1 1 0 0 1 1 B 0 1 0 1 0 1 0 1 Suma 0 1 1 0 1 0 0 1 51 Cout 0 0 0 1 0 1 1 1 Cuadro 5.6: @ AB 00 C @@ 0 1 0 01 11 10 1 0 1 0 1 3 2 1 0 1 0 4 5 7 6 @ AB 00 C @@ 0 0 0 4 11 10 0 1 0 1 3 2 0 1 01 1 1 1 5 7 6 Figura 5.12: Mapas K del sumador completo de salida es verdadera cuando hay mayorı́a de unos a la entrada. Usando estas expresiones para la suma y el acarreo, el sumador completo se puede implementar con compuertas NAND e inversores como se muestra en la figura 5.13. Sumadores de Dı́gitos Múltiples Un sumador de dı́gitos múltiples se puede hacer usando varios sumadores completos. Por ejemplo, un circuito para sumar 2 valores de 4 bits se puede construir a partir de cuatro sumadores completos como se muestra en la figura 5.14. Nótese las conexiones de los acarreos en el sumador de 4 bits. La entrada de acarreo a cada sumador es el acarreo de salida del sumador anterior. Puesto que la salida de cada sumador depende del acarreo del sumador anterior, cada sumador debe “esperar” el acarreo del sumador anterior. Esta propagación del acarreo frena el circuito sumador, especialmente si el número de bits del sumador se aumenta. Para ilustrar el efecto de la propagación del acarreo, calculemos el tiempo requerido para ejecutar una suma de varios bits. Para calcular el tiempo de la suma, debe determinarse el retardo asociado con cada sumador completo. Por ejemplo, supongamos que cada compuerta mostrada en el circuito del sumador completo de la figura 5.14 tiene un retardo de 10ns. Por lo tanto, la salida será válida después de 3 retardos de compuertas (inversor, NAND, NAND), o sea 30ns. La salida “acarreo” es válida después de 2 retardos (NAND, NAND), o sea 20ns. 52 CAPÍTULO 5. APLICACIONES COMBINACIONALES Figura 5.13: Circuito lógico del sumador completo Usando estas demoras, vemos que el acarreo de salida del bit 0 es válido después de 20ns. El bit de acarreo de la salida del bit 1 es válido 20ns después del bit 0, y ası́ sucesivamente. La salida del sumador de 4 bits no será válida hasta tanto C3 como S3 sean válidos. Por consiguiente, el tiempo total necesario para el sumador de 4 bits será: Cin a C0 = 20ns C0 a C1 = 20ns C1 a C2 = 20ns C2 a S3 = 30ns Tiempo de suma = 90ns A medida que el número de bits que se van a sumar aumenta, el efecto de la propagación del acarreo es aún más notorio. Por ejemplo, para un sumador de 32 bits el tiempo de suma serı́a: 31 × 20ns + 30ns = 650ns. Como se puede ver, el tiempo de suma es proporcional al número de bits que se van a sumar. 5.3. ANTICIPACIÓN DEL ACARREO (“CARRY LOOKAHEAD”) 53 Figura 5.14: Sumador de 4 bits 5.3 Anticipación del Acarreo (“Carry Lookahead”) El principal problema del circuito sumador de varios bits de la sección anterior es que la salida de cada sumador depende del acarreo de salida del sumador anterior. Si se pudiera determinar los valores de acarreo sin tener que esperar la propagación de los acarreos de las etapas anteriores, el tiempo de suma serı́a independiente del número de bits del sumador y por lo tanto, se reducirı́a. Para lograr esto, notemos que un término (sumador) producirá acarreo bajo dos condiciones. Primera: si ambas entradas son 1, se generará un acarreo sin importar el acarreo que entre. Esto lo denominaremos “condición generadora”. Segundo: si sólo una de las entradas es 1, se producirá acarreo si hubo acarreo de entrada, es decir, si la etapa anterior produjo acarreo. A esta situación la denominaremos “condición propagadora”, puesto que el acarreo de entrada será propagado o transmitido a la salida. Estas condiciones para un término “i” pueden representarse en álgebra booleana como: Gi =Ai Bi Gi =Ai Bi + Ai Bi (Condición generadora) (Condición propagadora) En resumen, un término producirá acarreo si 1) cumple la condición generadora (Gi ) o (2) si cumple la condición propagadora (Pi ) y hubo acarreo de entrada. Esto se puede representar como: Ci = Gi + (Pi )(Ci−1 ) (5.6) Usando esta relación, puede formarse una expresión para cada bit según se ilustra a continuación para un sumador de 4 bits: C0 = G0 + P0 .Cin C1 = G1 + P1 .C0 = G1 + P1 (G0 + P0 .Cin ) = G1 + P1 .G0 + P1 .P0 .Cin C2 = G2 + P2 .C1 54 CAPÍTULO 5. APLICACIONES COMBINACIONALES = G2 + P2 (G1 + P1 .G0 + P1 .P0 .Cin ) = G2 + P2 .G1 + P2 .P1 .G0 + P2 .P1 .P0 .Cin C3 = G3 + P3 .C2 = G3 + P3 (G2 + P2 .G1 + P2 .P1 .G0 + P2 .P1 .P0 .Cin ) = G3 + P3 .G2 + P3 .P2 .G1 + P3 .P2 .P1 .G0 + P3 .P2 .P1 .P0 .Cin ) Examinando estas ecuaciones, vemos que cada producto trata de determinar si un acarreo puede venir de un término anterior. Esto es posible sólo si un término anterior generó un acarreo y las etapas posteriores lo propagaron. Por ejemplo, miremos la ecuación que define a C3 . Para que la etapa 3 produzca un acarreo a partir de un acarreo producido por la etapa 0, las etapas 1,2 y 3 deben haberlo propagado; de este resulta el término P3 .P2 .P1 .G0 . Para determinar la efectividad del procedimiento de anticipación del acarreo, necesitamos determinar el tiempo necesario para calcular el acarreo con los términos mostrados anteriormente. Para simplificar el diagrama lógico notemos que la condición de propagación es simplemente la función OR EXCLUSIVO, que se puede escribir como: Pi = Ai Bi + Ai Bi = Ai Bi + Ai Bi (5.7) Usando esta equivalencia, podemos producir los términos Gi y Pi según se muestra en la figura 5.15 Figura 5.15: Generación de Gi y Pi Como puede verse, son 2 retardos de compuertas, es decir, 40 ns, para evaluar un término de acarreo. Las compuertas asociadas con la generación de la condición de propagación. Esto, conjuntamente con la naturaleza de dos niveles de las expresiones de acarreo, da como resultado un total de 4 retardos de tiempos de suma para un sumador de 4 bits y para un sumador de 32 bits se pueden calcular como sigue: 5.4. OTROS CIRCUITOS COMBINACIONALES IMPORTANTES 55 Tiempo de suma para un sumador de 4 bits: Ai Bi a Ci = 40ns Ci a Si = 30ns Tiempo de suma = 70ns Tiempo de suma para un sumador de 32 bits: Ai Bi a Ci = 40ns Ci a Si = 30ns Tiempo de suma = 70ns Como puede verse, el tiempo de suma es independiente del número de bits cuando se usa la técnica de anticipación del acarreo. Esto resulta de una mejora significativa en el tiempo de suma, especialemente cuando el número de bits del sumador crece. Desafortunadamente es bastante complicado implementar estas técnicas en forma completa para un número grande de bits. Por ejemplo, evaluar la expresión para el bit de acarreo más significativo de un sumador de N bits, requiere una compuerta OR de N+1 entradas y N compuertas AND desde 2 entradas hasta NH entradas. Para un sumador de 32 bits, esto significa una compuerta OR de 33 entradas y 32 compuertas AND, desde 2 hasta 33 entradas para el bit de acarreo más significativo. Debido a esta complejidad, la anticipación completa del acarreo sólo se hace de 4 a 8 bits a la vez. Por ejemplo, consideremos un sumador de 32 bits compuesto de 4 sumadores de 8 bits, cada uno con anticipación de acarreo. Con esta disposición, el acarreo debe propagarse entre los 4 sumadores pero el efecto de propagación es menos dramático que la propagación sobre 32 bits. Este sumador se muestra en la figura 5.16. Figura 5.16: Sumador de 32 bits usando sumadores de 8 bits 5.4 OTROS CIRCUITOS COMBINACIONALES IMPORTANTES Existen otros circuitos combinacionales comúnmente usados en circuitos digitales. Estos circuitos se diseñan fácilmente con las mismas técnicas que hemos estudiado hasta ahora. 5.4.1. Convertidores de Código Los circuitos digitales representan la información “humana” por medio de alguna clase de código. Por ejemplo, BCD es un código binario que permite representar los valores 56 CAPÍTULO 5. APLICACIONES COMBINACIONALES Entrada BCD A B C D 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 Salida F 1 F2 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 2421 F3 F4 0 0 0 1 1 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1 Cuadro 5.7: decimales desde el 0 hasta el 9. Ocasionalmente, se hace necesario convertir un código a otro. Por ejemplo, consideremos el diseño de un circuito que convierte de BCD a código 2421. BCD se denomina también código 8421 puesto que las posiciones de los bits están afectadas por un peso de 8, 4, 2, 1. De igual forma, el código 2421 indica que los pesos de cada posición son 2, 4, 2, 1. A partir de estas definiciones, puede armarse la tabla de verdad que se muestra en la tabla 5.7. Este convertidor se puede implementar con las técnicas estudiadas hasta ahora. 5.4.2. Comparadores A menudo se necesita comparar dos valores binarios. Dados dos valores binarios, un comparador produce una o varias salidas indicando igualdad, menor que, mayor que, y ası́ sucesivamente. Cuando se diseña un comparador, generalmente no es necesario derivar expresiones para cada salida como función de las entradas solamente. Por ejemplo, si A > B y A < B, se expresan como alguna función de las entradas, todas las otras relaciones se pueden expresar como función de las salidas. Por ejemplo, A es igual a B solamente si A no es mayor que B y B no es mayor que A. A = B ⇔ (A > B).(B > A) 5.4.3. (5.8) Decodificadores-Manejadores de Despliegues Los circuitos digitales a menudo se “comunican” con el mundo externo por medio de despliegues LED de siete segmentos tales como los que se encuentran en la calculadora. Estos despliegues constan de 7 LEDs individuales que se iluminan para formar diferentes dı́gitos. Un decodificador-manejador de despliegues se utiliza para iluminar apropiadamente esos segmentos basados en un valor de entrada. Por ejemplo, un decodificador-manejador de 5.4. OTROS CIRCUITOS COMBINACIONALES IMPORTANTES 57 despliegue BCD tiene 4 entradas (los 4 bits del dı́gito BCD) y siete salidas, una por cada segmento. Basado en el dı́gito BCD de entrada, las salidas de siete segmentos se deben disponer apropiadamente para formar el dı́gito en el despliegue. Existen 2 configuraciones básicas para los despliegues de 7 segmentos: ánodo común y cátodo común. En un despliegue de ánodo común, el ánodo o lado positivo de cada LED es común, como se muestra en la figura 5.17. Con estos despliegues, un LED individual se enciende si se conecta a tierra. Por lo tanto, un decodificador-manejador para un despliegue de ánodo común coloca su salida baja para encender el segmento. En un despliegue de cátodo común, el cátodo o lado negativo de cada LED es común, según se muestra en la figura 5.18. Para encender cada LED de los despliegues, debe conectarse el LED a un voltaje positivo. Por lo tanto, el manejador debe colocar su salida alta para encender un segmento. Figura 5.17: Despliegue con Ánodo Común Figura 5.18: Despliegue con Cátodo Común . 58 CAPÍTULO 5. APLICACIONES COMBINACIONALES Capı́tulo 6 Introducción a los PLD y a VHDL Conceptos básicos PLD: Programmable Logic Device PROM PAL GAL FPGA VHDL Entidad Arquitectura Puerto Modo de un puerto Señal Variable Configuración Declaración del paquete Cuerpo del paquete Tipos de datos Vectores Descripción funcional Descripción por flujo de datos Descripción estructural Saber Hacer Conocer las diferentes opciones de PLD. Reconocer la celda básica de un circuito programable. Conocer la estructura básica de un lenguaje de descripción de hardware como lo es VHDL. Conocer los diferentes componentes del lenguaje. 59 60 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL 6.1 Introducción a los dispositivos programables. 6.1.1. Introducción. Los dispositivos lógicos programables PLD, son una alternativa para el diseño de sistemas digitales y prototipos de baja escala de integración, esto se debe a la disponibilidad en el mercado y al soporte existente para las herramientas de desarrollo asistido por computador, CAD. 6.1.2. Dispositivos Lógicos Programables, PLD. Un dispositivo lógico programable o PLD por sus siglas en inglés (Programmable Logic Device), es un circuito integrado que contiene gran número de compuertas, flip-flops y registros internamente conectados. Estas conexiones son de dos tipos: fijas y programables. Las conexiones fijas son aquellas que no varı́an, mientras que las conexiones programables se pueden o no desconectar. Muchas de estas conexiones programables son tipo fusible, fusibles que son “quemados” durante la programación, permitiendo de esta manera configurar nuestra aplicación dentro de un PLD. Algunas de las caracterı́sticas principales de los PLD pueden ser: Capacidad de reprogramación, pueden ser programables o reprogramables. Tipo de tecnologı́a, bien sea CMOS o TTL. Tipo de salida, activa baja o alta o configurable. Consumo de potencia. Tiempo de retardos. Niveles de tensión alimentación, 3 o 5 Voltios. Clasificación de los PLD. Un PLD consta de arreglos de compuertas AND conectados a un arreglo de compuertas OR a través de elementos programables, generalmente del tipo fusible. Un diagrama de bloques de la estructura interna de un PLD se muestra en la figura 6.1. Según sean programables sus arreglos, los PLD se pueden clasificar en: PROM, arreglo AND fijo, arreglo OR programable. PLA, ambos arreglos programables. 6.1. INTRODUCCIÓN A LOS DISPOSITIVOS PROGRAMABLES. 61 Figura 6.1: Estructura interna de un PLD Figura 6.2: Estructura interna de una PROM PAL, Arreglo AND programable y arreglo OR fijo. GAL, Arreglo AND reprogramable y arreglo OR fijo, además de lógica de salida programable. FPGA, son arreglos de compuertas programables en campo, está formado por bloques lógicos configurables. PROM, Memorias de Sólo Lectura. Son también conocidas como PLE (elementos lógicos programables), constan de un arreglo AND fijo, el cual decodifica las direcciones, 2 entradas, conectado a un arreglo OR programable. En la figura 6.2 se muestra una PROM de dos entradas, cuatro lı́neas de producto y cuatro salidas. PAL, Lógica de Arreglos Programables. Este dispositivo cuenta con un arreglo AND programable y un arreglo OR fijo, además tiene la posibilidad de realimentación de la salida, algo que lo hace muy útil para el caso en que se necesite conocer un estado intermedio de una función. Además la arquitectura PAL tiene a su salida un buffer (YES o NOT) en el cual se puede implementar lógica de tercer estado, y tener puertos bidireccionales, de entrada/salida. La salida de este arreglo puede estar conectada un registro (flip-flop), la cual se realimenta hacia el arreglo AND, este registro permite la 62 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL Figura 6.3: Estructura interna de una PAL en modo combinacional Figura 6.4: Estructura interna de una PAL con registros. implementación de lógica secuencial y máquinas de estado. En la figura 6.3 se muestra un PAL en su modo combinacional, mientras que en la figura 6.4 se muestra un PAL con la salida conectada a un flip - flop tipo D. GAL, Lógica de Matriz Genérica. En esta tecnologı́a los fusibles de un PAL son reemplazados por un bloque E2 CMOS. Su lógica de salida es programable y no se habla de una arreglo OR, sino de una OLMC, macro celda lógica de salida. Esta permite el trabajo en modo combinacional, buffer de tercer estado y modo registrado. Con el GAL se pueden emular los PAL. En la figura 6.5 se muestra el detalle de una macro celda lógica de salida. La GAL puede configura en tres modos de operación: Sencillo o simple , en donde se trabaja lógica combinacional sin salida de tercer estado. En la figura 6.6 se observa la macro celda en modo combinacional, como puede observarse, la salida queda definida como entrada o salida. Complejo , en donde se trabaja lógica combinacional con salida de tercer estado controlada, lo cual permite usar un pin como entrada y salida dentro de un mismo 6.1. INTRODUCCIÓN A LOS DISPOSITIVOS PROGRAMABLES. Figura 6.5: Macro celda de salida de un GAL. Figura 6.6: Macro celda lógica en modo combinacional. 63 64 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL Figura 6.7: Arquitectura de una macro celda de la familia MAX7000 de Altera. diseño. Registrado , el cual hace que cada macro celda de salida funcione en una configuración combinacional con salida de tercer estado o un modo sincrónico con un flip - flop tipo D sincronizado con una señal de reloj común a todas las macro celdas. Durante la programación se elige el modo de trabajo de la GAL de acuerdo a la función a realizar. FPGA, Arreglo de Compuertas Programables en Campo. Una FPGA está formada por bloques de arreglos lógicos, LAB, y cada LAB está conformado por 16 bloques modulares o macro celdas, como la mostrada en la figura 6.7. Esta arquitectura permite alta densidad (20 000 compuertas), alta velocidad (70 MHz), retardos de 15 nano segundos y consumo máximo de 45 mA, en presentaciones de 44 a 288 pines. Los LAB se conectan entre sı́ por medio de un PIA, arreglo de interconexión programable, el cual optimiza la relación velocidad - consumo. En la mayorı́a de las arquitecturas PLD, cuando un pin de I/O es usado como entrada, la macro celda asociada no puede ser usada para ejercer otras funciones, en esta arquitectura se elimina este problema por desacoplamiento de los pines de I/O. Lo que permite que estas macro celdas permanezcan aptas para ser usadas para la implementación de lógica interna. Ventajas de los PLD. La conveniencia de la lógica programable está en la habilidad para realizar un producto que no se encuentre en el mercado. Se pueden incluir otras ventajas como: 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 65 Fácil obtención de prototipos. Se pueden realizar modificaciones a un diseño sin mayores traumatismos. Estos diseños se pueden emplear como módulo, y el diseño final puede ser la interconexión de varias partes. Mayor confiabilidad. Menos integrados, menos conexiones, tarjetas más sencillas. Fácil diseño. Gracias a la amplia disponibilidad de herramientas CAD, se puede especificar un diseño a alto nivel, realizar sı́ntesis lógica y selección y adaptación automática de un diseño a un dispositivo especı́fico. Además simular y realizar pruebas y generar documentos. Mayor rendimiento, con retardos de 15 nano segundos para PLD de tecnologı́a CMOS y de 10 nano segundos para PLD de familia TTL. Y menores costos y tiempo de desarrollo de cualquier aplicación. 6.2 VHDL: Su organización y arquitectura. 6.2.1. Introducción. Tal como lo indican sus siglas, VHDL (Hardware Description Language) es un lenguaje orientado a la descripción o modelado de sistemas digitales; es decir, se trata de un lenguaje mediante el cual se puede describir, analizar y evaluar el comportamiento de un sistema electrónico digital. VHDL es un lenguaje poderoso que permite la integración de sistemas digitales sencillos, elaborados o ambos en un dispositivo lógico programable, sea de baja capacidad de integración como un GAL, o de mayor capacidad como los CPLD y FPGA. 6.2.2. Unidades básicas de diseño. La estructura general de un programa en VHDL está formada por módulos o unidades de diseño, cada uno de ellos compuesto por un conjunto de declaraciones e instrucciones que definen, describen, estructuran, analizan y evalúan el comportamiento de un sistema digital. Existen cinco tipos de unidades de diseño en VHDL; declaración de entidades (entity declaration), arquitectura (architecture), configuración (configuration), declaración del paquete (package declaration) y el cuerpo del paquete (package body). De éstas cinco unidades, son obligatorias al menos una entidad y una arquitectura. Las declaraciones de entidad, paquete y configuración se consideran unidades de diseño primarias, mientras que la arquitectura y el cuerpo del paquete son unidades de diseño secundarias porque dependen de una entidad primaria que se analiza antes que ellas. 66 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL (a) (b) (c) Figura 6.8: 6.8(a) Descripción a nivel de compuerta. 6.8(b) Sı́mbolo funcional de la entidad. 6.8(c) Diagrama a bloques relativo de la entidad. 6.2.3. Entidad Una entidad (entity) es el bloque elemental de diseño en VHDL. Las entidades son todos los elementos electrónicos (sumadores, contadores, compuertas, flip-flops, memorias, multiplexores, etc.) que forman de manera individual o en conjunto un sistema digital. La entidad puede representarse de muy diversas maneras; por ejemplo, la figura ?? muestra la arquitectura de un sumador completo a nivel de compuertas; ahora bien, esta entidad se puede representar a nivel de sistema indicando tan sólo las entradas (Cin, A y B) y salidas (SUMA y Cout) del circuito: figura ??. De igual forma, la integración de varios subsistemas (medio sumador) puede representarse mediante una entidad, figura ??. Los subsistemas pueden conectarse internamente entre sı́; pero la entidad sigue identificando con claridad sus entradas y salidas generales. 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 67 Figura 6.9: Comparador de igualdad. Puertos de entrada y salida. Cada una de las señales de entrada y salida en una entidad son referidas como puertos, los cuales son similares a una terminal (pin) de un sı́mbolo esquemático. Todos los puertos que son declarados deben tener un nombre, un modo y un tipo de dato. El nombre se utiliza para referenciar al puerto; el modo permite definir la dirección que tomará la información, es decir, si es de entrada o de salida, y el tipo define qué clase de información se trasmitirá por el puerto. Por ejemplo, respecto a los puertos de la entidad que representan a un comparador de igualdad (figura 6.9), las variables a y b denotan los puertos de entrada y la variable c se refiere al puerto de salida. Modos Como ya se mencionó, el modo permite definir la dirección en la cual el dato es transferido a través de un puerto. El modo puede tener uno de cuatro valores: in (entrada), out (salida), inout (entrada/salida) y buffer. Modo in. Se refiere a las señales de entrada a la entidad. Este sólo es unidireccional y nada más permite el flujo de datos hacia dentro de la entidad. Modo out. Indica las señales de salida de la entidad. Modo inout. Permite declarar un puerto de forma bidireccional, es decir, de entrada/salida; además permite la retroalimentación de señales hacia dentro o hacia afuera de la entidad. Modo buffer. Permite hacer retroalimentaciones internas dentro de la entidad, pero a diferencia del modo inout, el puerto declarado se comporta como una terminal de salida. Tipos de datos Los tipos se refieren a las diversas clases de valores (datos) que el diseñador establece para los puertos de entrada y salida dentro de una entidad; se asignan de acuerdo con las 68 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL Figura 6.10: Modos y el curso de sus señales. caracterı́sticas de un diseño en particular. Algunos de los tipos más utilizados en VHDL son: Bit, el cual tiene valores de 0 y 1. Boolean (booleano) que define valores de verdadero y falso en una expresión. Bit vector (vector de bits) que representa un conjunto de bits para cada variable de entrada o salida. Integer (entero) que representa un número entero. Los anteriores son sólo algunos de los tipos que maneja VHDL. 6.2.4. Declaración de entidades Como se mencionó en la sección ?? (Unidades básicas de diseño), los módulos elementales en el desarrollo de un programa dentro del lenguaje de descripción de hardware (VHDL) son la entidad y la arquitectura. La declaración de una entidad consiste en la descripción de las entradas y salidas de un circuito de diseño identificado como entity (entidad); es decir, la declaración señala las terminales o pines de entrada y salida de la entidad de diseño. Por ejemplo, la forma de declarar la entidad correspondiente al circuito sumador de la figura ?? se muestra a continuación: 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 1 2 3 4 5 6 69 -- Declaración de la entidad de un circuito sumador entity sumador is port (A , B , Cin : in bit ; SUMA , Cout : out bit ) ; end sumador ; Listado 6.1: Declaración de la entidad de la figura ?? Los números de las lı́neas (1, 2, 3, 4, 5) no son parte del código; se usan como referencia para explicar alguna sección en particular. Las palabras en negrilla están reservadas por el lenguaje de programación VHDL; esto es, tiene un significado especial para el programa; el diseñador asigna los otros términos. La lı́nea 1 inicia con dos guiones (–), los cuales indican que el texto que está a la derecha es un comentario cuyo objetivo es documentar el programa; el compilador ignora todos los comentario. En la lı́nea 2 se inicia la declaración de la entidad con la palabra reservada entity, seguida del identificador o nombre de la entidad (sumador) y la palabra reservada is. Los puertos de entrada y salida (port) se declaran en las lı́neas 3 y 4, respectivamente - en este caso los puertos de entrada A, B y Cin -, mientras que SUMA y Cout representan los puertos de salida. El tipo de dato utilizado para todos los puertos es bit, lo cual indica que sólo pueden manejarse valores de ’0’y ’1’lógicos. Por último, en la lı́nea 5 termina la declaración de entidad con la palabra reservada end, seguida del nombre de la entidad (sumador). ?????? Identificadores Los identificadores son simplemente los nombres que se usan para referir variables, señales, procesos, etc. Pueden ser números, letras del alfabeto y guiones bajos ( ) que separen caracteres y no tienen una restricción en cuanto a su longitud. Todos los identificadores deben seguir las reglas que aparecen en la tabla 6.1. VHDL tiene una lista de palabras reservadas que no son válidos como identificadores (vea apéndice A). 70 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL Regla El primer carácter siempre es una letra mayúscula o minúscula. El segundo carácter no puede ser un guión bajo. Dos guiones juntos no son permitidos. Un identificador no puede utilizar sı́mbolos. Incorrecto 4sumas S 4bits Resta 4 Clear#8 Correcto Suma4 S4 bits Resta 4 Clear 8 Cuadro 6.1: Especificaciones para la escritura de identificadores. Figura 6.11: Entidad representada por vectores. 6.2.5. Diseño de entidades mediante vectores La entidad sumador realizada en el circuito del listado anterior, usa bits individuales, los cuales sólo pueden representar dos valores lógicos (0 o 1). De manera general, en la práctica se utilizan conjuntos (palabras) de varios bits; en VHDL las palabras binarias se conocen como vectores de bits, de la misma manera como los arreglos de los lenguajes de programación convencionales. Como ejemplo considérense los vectores de 4 bits que se muestran a continuación: vector A = (A3 , A2 , A1 , A0 ) (6.1) vector B = (B3 , B2 , B1 , B0 ) (6.2) vector SU M A = (S3 , S2 , S1 , S0 ) (6.3) En la figura 6.11 se observa la entidad del sumador analizado antes, sólo que ahora las entradas A, B y la salida SUMA incorporan vectores de 4 bits en sus puertos. Obsérvese cómo la entrada Cin y la salida Cout son de un bit. Para describir en VHDL una configuración que utilice vectores se utiliza la sentencia bit vector, mediante la cual se especifican los componentes de cada uno de los vectores utilizados. La parte del código que se usa para declarar un vector dentro de los puertos es el siguiente: port ( vector A, vector B : in bit vector (3 downto 0); vector SUMA : out bit vector (3 downto 0)); 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 71 La declaración define los vectores (A, B y SUMA) con cuatro componentes distribuidos en orden descendente por medio del comando: 3 downto 0 (3 hasta 0) Los cuales se agrupan de la siguiente manera. vector A(3) = A3 vector B(3) = B3 vector SU M A(3) = S3 vector A(2) = A2 vector B(2) = B2 vector SU M A(2) = S2 vector A(1) = A1 vector B(1) = B1 vector SU M A(1) = S1 vector A(0) = A0 vector B(0) = B0 vector SU M A(0) = S0 Una vez que se ha establecido el orden en que aparecerán los bits enunciados en cada vector, no se puede modificar, a menos que se utilice el comando to: 0 to 3 (0 hasta 3) que indica el orden de aparición en sentido ascendente. Declaración de entidades mediante librerı́as y paquetes. Una parte importante en la programación con VHDL radica en el uso de librerı́as y paquetes que permiten declarar y almacenar estructuras lógicas, seccionadas o completas que facilitan el diseño. Una librerı́a o biblioteca es un lugar al que se tiene acceso para utilizar las unidades de diseño predeterminadas por el fabricante de la herramienta y su función es agilizar el diseño. En VHDL se encuentran definidas dos librerı́as llamadas ieee y work. En una librerı́a también se permite almacenar el resultado de la compilación de un diseño, con el fin de utilizar en uno o varios programas. La librerı́a work es el lugar establecido donde se almacenan los programas que el usuario va generando. Esta librerı́a se encuentra siempre presente en la compilación de un diseño y los diseños se guardan en ella mientras no se especifique otra. Un paquete es una unidad de diseño que permite desarrollar un programa en VHDL de una manera ágil, debido a que contiene algoritmos preestablecidos (sumadores, restadores, contadores, etc.) que ya tienen optimizado su comportamiento. Por esta razón, el diseñador no necesita definir paso a paso una nueva unidad de diseño si ya se encuentra almacenada en algún paquete - en cuyo caso basta con llamarla y especificarla en el programa -. Por lo tanto, un paquete no es más que una unidad de diseño formada por declaraciones, programas, componentes y subprogramas, que incluyen los diversos tipos de datos (bit, 72 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL booleano, std logic), empleados en la programación en VHDL y que suelen formar parte de las herramientas en software. Por último, cuando en el diseño se utiliza algún paquete es necesario llamar a la librerı́a que lo contiene. Para esto se utiliza la siguiente declaración: library ieee; Lo anterior permite el uso de todos los componentes incluidos en la librerı́a ieee. En el caso de la librerı́a de trabajo (work), su uso no requiere la declaración library, dado que la carpeta work siempre está presente al desarrollar un diseño. Paquetes El paquete std logic 1164 (estándar lógico 1164) que se encuentra en la librerı́a ieee contiene todos los tipos de datos que suelen emplearse en VHDL (std logic vector, std logic, entre otros). El acceso a la información contenida en un paquete se hace por medio de la sentencia use, seguida del nombre de la librerı́a y del paquete, respectivamente: use nombre liberı́a.nombre paquete.all; por ejemplo: use ieee.std logic 1164.all; En este caso ieee es la librerı́a, std logic 1164 es el paquete y la palabra reservada all indica que se pueden usar todos los componentes almacenados en el paquete. El paquete numeric std define funciones para realizar operaciones entre diferentes tipos de datos (sobrecargados); además, los tipos pueden representarse con signo o sin éste. El paquete numeric bit define tipos de datos binarios con signo o sin éste. El paquete std arith define funciones y operadores aritméticos, como igual (=), mayor que ( >), menor que (<), entre otros. 6.2.6. Arquitecturas Una arquitectura (architecture) se define como la estructura que describe el funcionamiento de una entidad, de tal forma que permita el desarrollo de los procedimientos que se 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 73 Figura 6.12: Descripción funcional de un comparador de igualdad de dos bits. llevarán a cabo con el fin de que la entidad cumpla las condiciones de funcionamiento deseadas. La definición de una arquitectura se puede realizar utilizando tres enfoques, a saber: Enfoque funcional. Enfoque por flujo de datos. Enfoque estructural. Descripción funcional Es en la figura 6.11 se describe funcionalmente el circuito comparador. Se trata de una descripción funcional porque expone la forma en que trabaja el sistema; es decir, las descripciones consideran la relación que hay entre las entradas y las salidas del circuito, sin importar cómo esté organizado en su interior. Para este caso: El código que representa el circuito de la figura 6.2.6 se muestra en el siguiente listado: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -- Ejemplo de una descripción funcional library ieee ; use ieee . std_logic_1164 . all ; entity comparador is port ( a , b : in bit_vector ( 1 downto 0) ; c : in bit ) ; end comparador ; architecture funcional of comparador is begin compara : process (a , b ) begin if a = b then c <= ’1 ’; else 74 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL 16 17 18 19 20 c <= ’0 ’; end if ; end process compara ; end funcional ; Listado 6.2: Arquitectura funcional de un comparador de igualdad de 2 bits. Nótese cómo la declaración de la entidad (entity) se describe en las lı́neas de la 1 a la 7; la arquitectura se incluye de la lı́nea 8 a la 18, Las lı́neas 10, 11 y 17 corresponden al marco del proceso (process) caracterı́stico de una descripción funcional. Las lı́neas 12 a la 17 detallan el algoritmo elegido para describir el proceso, en éste caso una estructura if∼then∼else Como se puede observar, la declaración funcional se basa principalmente en el uso de procesos y de declaraciones secuenciales, de forma análoga a los algoritmos clásicos de los lenguajes de programación convencionales. Descripción por flujo de datos La descripción por flujo de datos indica la forma en que los datos se transforman al pasar por el circuito. Este tipo de descripciones permite definir el flujo que tomarán los datos entre módulos encargados de realizar operaciones. En este tipo de descripción se pueden utilizar dos formatos mediante instrucciones when∼ else (cuando∼si no) o por medio de ecuaciones booleanas. 1. Descripción por flujo de datos mediante when∼else A continuación se muestra el código del comparador de igualdad de dos bits descrito antes (figura 6.2.6). Nótese que la diferencia entre los listados radica en la eliminación del proceso y en la descripción sin declaraciones secuenciales (if∼then∼else). En VHDL se manejan dos tipos de declaraciones: secuenciales y concurrentes. Una declaración secuencial de la forma if then else se utilizó en el listado 6.2 dentro del proceso, donde su ejecución debe seguir un orden para evitar la pérdida de la lógica descrita. En cambio, en una declaración concurrente esto no es necesario, ya que no importa el orden en que se ejecutan. Tal es el caso del listado 6.3. 1 2 3 4 -- Ejemplo de declaración de la entidad de un comparador library ieee ; use ieee . std_logic . all ; entity comp is 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 75 Figura 6.13: a) Entidad del comparador de dos bits. b) Comparador de dos bits realizado con compuertas. 5 6 7 8 9 10 11 12 13 port (a , b : in bit_vector (1 downto 0) ; c : out bit ) ; end comp architecture f_datos of comp is begin c <= ’1 ’ when ( a = b ) else end f_datos ’0 ’ Listado 6.3: Arquitectura por flujo de datos. 2. Descripción por flujo de datos mediante ecuaciones booleanas Otra forma de describir el circuito comparador de dos bits es mediante la obtención de sus ecuaciones booleanas figura 6.13. En el listado 6.4 se observa este desarrollo. El interior del circuito comparador de la figura ?? a puede representarse por medio de compuertas básicas [figura ??] y este circuito puede describirse mediante la obtención de sus ecuaciones booleanas. 1 2 -- Ejemplo de declaración de la entidad de un comparador library ieee ; use ieee . std_logic_1164 . all ; 76 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL Figura 6.14: Representación esquemática de un comparador de 2 bits. 3 4 5 6 7 8 9 10 11 12 13 entity comparador is port ( a , b : in c : out end comparador ; bit_vector (1 downto 0) ; bit ) ; architecture booleana of comparador is begin c <= ( a (1) xnor b (1) and a (0) xnor b (0) ) ; end booleana ; Listado 6.4: Arquitectura de forma de flujo de datos construido por medio de ecuaciones boolenas. La forma de flujo de datos en cualquiera de sus representaciones describe el camino que los datos siguen al ser transferidos de las operaciones efectuadas entre las entradas a y b a la señal de salida c. Descripción estructural Como se nombre indica, una descripción estructural basa su comportamiento en modelos lógicos establecidos (compuertas, sumadores, contadores, etc.). Según veremos más adelante, el usuario puede diseñar estas estructuras y guardarlas para su uso posterior o tomarlas de los paquetes contenidos en las librerı́as de diseño del software que es esté utilizando. En la figura 6.14 se encuentra un esquema del circuito comparador de igualdad de 2 bits, el cual está formado por compuertas nor-exclusivas y una compuerta AND. En nuestro caso, cada compuerta (modelo lógico) se encuentra dentro del paquete gatespkg, del cual se toman para estructurar el diseño. A su vez, este tipo de arquitecturas estándares se conocen como componentes, que al interconectarse por medio de señales 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 77 internas, (x0 , x1 ) permiten proponer una solución. En VHDL esta conectividad se conoce como netlist 1 o listado de componentes. Para iniciar la programación de una entidad de manera estructural, es necesario la descomposición lógica del diseño en pequeños submódulos (jerarquizar), los cuales permiten analizar de manera práctica el circuito, ya que la función de entrada/salida es conocida. En nuestro ejemplo se conoce la función de salida de las dos compuertas xnor, por lo que al unirlas a la compuerta and, la salida c es el resultado de la operación and efectuada en el interior a través de las señales x0 y x1 (figura 6.14). Es importante resaltar que una jerarquı́a en VHDL se refiere al procedimiento de dividir en bloques y no a que un bloque tenga mayor jerarquı́a (peso) que otro. Esta forma de dividir el problema hace de la descripción estructural una forma sencilla de programar. En el contexto del diseño lógico esto es observable cuando se analiza por separado alguna sección de un sistema integral. En el listado 6.5 se muestra el código del programa que representa al esquema de la figura 6.14. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 library ieee ; use ieee . std_logic_1164 . all ; entity comparador is port ( a , b : in bit_vector (0 to 1) : c : out bit ) ; end comparador ; use work . compueta . all ; architecture estructural of signal x : bit_vector (0 to begin U0 : xnor2 port U1 : xnor2 port U2 : and2 port end estructural ; compuerta is 1) ; map map map ( a (0) , ( a (1) , ( x (0) , b (0) , b (1) , x (1) , x (0) ) ; x (1) ) ; c); Listado 6.5: Descripción estructural de un comparador de igualdad de 2 bits. En el código se puede ver que en la entidad nada más se describen las entradas y salida del circuito (a, b y c), según se ha venido haciendo (lı́neas 3 a la 6). Los componentes xnor y and no se declaran debido a que se encuentran en el paquete de compuertas (gatespkg), el cual a su vez está dentro de la librerı́a de trabajo (work), lı́nea 7. 1 Un netlist se refiere a la forma como se encuentran conectados los componentes dentro de una estructura y las señales que propician esta interconexión. 78 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL En la lı́nea 8 se inicia la declaración de la arquitectura estructural. El algoritmo propuesto (lı́neas 11 a 13) describe la estructura de la siguiente forma: cada compuerta se maneja como un bloque lógico independiente (componente) del diseño original, al cual se le asigna una variable temporal (U0, U1 y U2); la salida de cada uno de estos bloques se maneja como una señal lı́nea 9, signal x (x0 y x1), las cuales se declaran dentro de la arquitectura y no en la entidad, debido a que no representan a una terminal (pin) y sólo se utilizan para conectar bloques de manera interna a la entidad. Por último, podemos observar que la compuerta and recibe las dos señales provenientes de x (x0 y x1), ejecuta la operación y asigna el resultado a la salida c del circuito. Comparación entre los estilos de diseño El estilo de diseño utilizado en la programación depende del diseñador y de la complejidad del proyecto. Por ejemplo, un diseño puede describirse por medio de ecuaciones booleanas, pero si es muy extenso quizá sea más apropiado emplear estructuras jerárquicas para dividirlo; ahora bien, si se requiere diseñar un sistema cuyo funcionamiento dependa sólo de sus entradas y salidas, es conveniente utilizar la descripción funcional, la cual presenta la ventaja de requerir menos instrucciones y el diseñador no necesita un conocimiento previo de cada componente del circuito. 6.2.7. Resumen de VHDL Generalidades Este lenguaje fue desarrollado inicialmente por el Departamento de Defensa de los EE.UU., siendo posteriormente estandarizado por IEEE en 1987 y en 1993. Las sentencias del lenguaje se pueden clasificar como sigue: Sentencias declarativas: permiten declarar tipos de datos, variables, señales, etc. Sentencias ejecutivas, las cuales clasificamos a su vez ası́: • Sentencias de asignación: asignan valor a variables o señales • Sentencias de control de flujo: lazos de repetición, condicionales, etc. Las sentencias ejecutivas también se pueden clasificar en: • Concurrentes: no importa el orden de ejecución • Secuenciales: es importante el orden de ejecución, tal como en los lenguajes de programación convencionales. Se pueden aplicar tres estilos diferentes para desarrollar un sistema: 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 79 • Estructural: se definen los elementos que hacen parte del sistema y la forma como se conectan. • Funcional: el comportamiento del sistema se describe mediante un algoritmo. • Flujo de datos: enfoque mixto de los dos anteriores. Elementos del lenguaje En cada sentencia del lenguaje, se utilizan elementos que pueden ser: Identificadores: nombre de un elemento tal como circuito, señal, variable, etc. Palabras reservadas propias del lenguaje, entre las cuales podemos citar las siguientes: architecture, begin, bus, end, entity, if, and, or, nand, port, register. Literales o constantes, que pueden ser numéricas, carácter, cadena de caracteres, cadena de bits. Por ejemplo: 345, 2E5, ?????Á’, “Digitales”, X“FF”, b“101000” Igualmente, se utilizan separadores que van entre los elementos del lenguaje, tales como espacios, tabuladores, finales de lı́nea. Finalmente, se pueden incluir comentarios, los cuales empiezan por dos guiones consecutivos y terminan con un fin de lı́nea. Variables y tipos de datos Los objetos que se pueden manipular en VHDL son: Variables , que se declaran como: Variable identificador: subtipo [:=expresión] Por ejemplo: variable contador: positive:= 100; Constantes , que se declaran como: Constant identificador: subtipo [:= expresión] Señales , las cuales permiten el modelado de circuitos. Son similares a las variables, pero se diferencian en la forma en que se actualiza el valor. Una variable lo hace al ejecutar la sentencia correspondiente, mientras que no ocurre lo mismo con las señales. Se definen ası́: Signal identificador: subtipo [tipo señal] [:= expresión] En donde tipo señal puede ser register o bus. Por ejemplo: signal OPERADOR: bit vector (8 downto 0); 80 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL Los tipos de datos definidos en el paquete STANDARD son los siguientes: BOOLEAN, que permite los valores FALSE y TRUE. BIT, que permite los valores ’0’y ’1’ CHARACTER, que permite los valores ASCII estándar INTEGER, con rango correspondiente a 16 bits REAL, tal como los lenguajes convencionales TIME STRING, como arreglo de caracteres BIT VECTOR, como arreglo de bits Entidad y arquitectura Los dos bloques básicos de VHDL son Entidad (entity), la cual define la interfaz del sistema, y Arquitectura (architecture), en donde se define el comportamiento o diseño del circuito. El bloque entidad describe el modelo de entradas y salidas del sistema, o del elemento del sistema. El bloque arquitectura describe el comportamiento del sistema o elemento. Conviene anotar que una entidad puede tener varias arquitecturas. Una combinación particular entidad-arquitectura se puede declarar como componente. Sentencias concurrentes y secuenciales Las sentencias secuenciales son aquellas que se ejecutan una después de la otra, de la misma manera que en cualquier lenguaje de programación convencional. Dado que en los sistemas electrónicos aparecen actividades que no son de naturaleza secuencial sino paralela o concurrente, VHDL contempla el mecanismo de los procesos (process), los cuales se ejecutan todos en forma paralela. Cada proceso se describe mediante un bloque de sentencias, las cuales se ejecutan en forma secuencial. Estilos de descripción La descripción de un sistema digital puede hacerse empleando uno de los siguientes estilos, o también combinaciones de ellos: 6.2. VHDL: SU ORGANIZACIÓN Y ARQUITECTURA. 81 Enfoque estructural: la descripción se realiza detallando cada uno de los componentes del sistema y sus interconexiones. Enfoque de trayectorias de datos: la descripción se realiza en términos de las transformaciones que sufren los datos al pasar por el sistema. Se utilizan principalmente ecuaciones lógicas. Enfoque algorı́tmico: La descripción del sistema se hace detallando el algoritmo que desarrolla. Unidades, paquetes y bibliotecas VHDL permite que se desarrollen los diseños de manera jerárquica. Las bibliotecas permiten catalogar elementos que se van a utilizar en los diseños, no siendo necesario cada vez volverlos a definir. Las unidades definidas por VHDL son de dos tipos: Primarias, de naturaleza declarativa, y son: • Entidad (entity): especifica la interfaz de un elemento o sistema. • Paquete (package): formado por un conjunto de declaraciones de elementos, funciones, subprogramas, orientadas a que el usuario las pueda utilizar pero sin suministrar los detalles de implementación de los mismos. • Configuración (configuration): permite asociar a cada componente una entidad. Secundarias, de naturaleza ejecutiva, y son: • Arquitectura (architecture): describe la implementación de una entidad. • Cuerpo de paquete (package body): describe la implementación de los componentes de un paquete. Los componentes, que son asociaciones entity-arquitecture, se suelen agrupar en paquetes, los cuales se reúnen como bibliotecas. 82 CAPÍTULO 6. INTRODUCCIÓN A LOS PLD Y A VHDL Capı́tulo 7 Circuitos Combinacionales en VHDL Conceptos básicos Variables lógicas o binarias Saber Hacer Reconocer los sı́mbolos de las operaciones lógicas. Manipular ecuaciones lógicas usando conceptos de álgebra booleana. 83 84 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL Figura 7.1: Sı́mbolo lógico del 74x138. 7.1 Decodificador 3 a 8 MÉTODO CONVENCIONAL Un decodificador es un circuito lógico que detecta la presencia de una determinada combinación de bits (código) en sus entradas y señala la presencia de este código mediante un cierto nivel de salida. En su forma más general, un decodificador tiene n lı́neas de entrada y 2n lı́neas de salida. El 74x138 es un decodificador 3 a 8. Su sı́mbolo lógico, tabla de verdad y estructura interna se muestran a continuación: Las entradas de selección son A, B y C, las salidas son Y0-Y7, activas bajas. Las lı́neas G1 , G2A y G2B se emplean como habilitación. DISEÑO CON VHDL El siguiente es el programa en VHDL para el decodificador 3 a 8: 1 2 3 4 5 6 7 8 9 10 11 library IEEE ; use IEEE . std_logic_1164 . all ; entity V74x138 is port ( G1 , G2A , G2B : in std_logic ; A : in std_logic_vector (2 downto 0) ; Y : out std_logic_vector (0 to 7) ) ; end V74x138 ; architecture V74x138_a of V74x138 is signal Y_i : std_logic_vector (0 to 7) ; begin 7.1. DECODIFICADOR 3 A 8 Entradas de habilitación 85 Entradas de selección Salidas G1 G2A G2B A B C Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 1 1 0 1 1 1 1 1 1 1 0 0 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 0 1 1 1 1 0 1 1 1 1 0 0 1 0 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 0 X X 1 1 1 1 1 1 1 1 1 1 1 X 1 X 1 1 1 1 1 1 1 1 1 1 1 X X 1 1 1 1 1 1 1 1 1 1 1 1 Cuadro 7.1: Tabla de verdad del 74x138 Figura 7.2: Estructura interna del 74x138. 86 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL Figura 7.3: Sı́mbolo lógico del 7449. 12 13 14 15 16 17 18 19 20 21 22 23 24 with A select Y_i <= " 01111111 " when " 000 " , " 10111111 " when " 001 " , " 11011111 " when " 010 " , " 11101111 " when " 011 " , " 11110111 " when " 100 " , " 11111011 " when " 101 " , " 11111101 " when " 110 " , " 11111110 " when " 111 " , " 11111111 " when others ; Y <= Y_i when ( G1 and not G2A and not G2B ) = ’1 ’ else " 11111111 " ; end V74x138_a ; Listado 7.1: Decodificador 3 a 8 Todas las variables lógicas del programa se definen del tipo std logic. Esto permite especificar su valor por medio de cadenas de caracteres. Las entradas de selección (A2downto0) y las salidas activas bajas (Y 0to7) se definen como vectores. La declaración select enumera los 8 casos de decodificación y asigna el valor adecuado a la variable intermedia Y i. Este valor se asigna a la salida si todas las entradas de habilitación son correctas. 7.2 Decodificador BCD a 7-Segmentos (7449) MÉTODO CONVENCIONAL 7.2. DECODIFICADOR BCD A 7-SEGMENTOS (7449) 87 Este decodificador tiene 5 entradas, las entradas A, B, C, D corresponden al dato en BCD y la entrada BI es una entrada de blanqueo. La siguiente tabla de verdad muestra la función para cada segmento del decodificador. Decimal Entradas Salidas D C B A BI A B C D E F G 0 0 0 0 0 0 1 1 1 1 1 1 0 1 0 0 0 1 0 0 1 1 0 0 0 0 2 0 0 1 0 0 1 1 0 1 1 0 1 3 0 0 1 1 0 1 1 1 1 0 0 1 4 0 1 0 0 0 0 1 1 0 0 1 1 5 0 1 0 1 0 1 0 1 1 0 1 1 6 0 1 1 0 0 0 0 1 1 1 1 1 7 0 1 1 1 0 1 1 1 0 0 0 0 8 0 0 0 0 0 1 1 1 1 1 1 1 9 0 0 0 1 0 1 1 1 1 0 0 1 10 1 0 1 0 0 0 0 0 1 1 0 1 11 1 0 1 1 0 0 0 1 1 0 0 1 12 1 1 0 0 0 0 1 0 0 0 1 1 13 1 1 0 1 0 1 0 0 1 0 1 1 14 1 1 1 0 0 0 0 0 1 1 1 1 15 1 1 1 1 0 0 0 0 0 0 0 0 BI X X X X 1 0 0 0 0 0 0 0 Cuadro 7.2: Tabla de verdad del 7449 Para implementar la tabla con compuertas se utilizo la herramienta CircuitMaker, en la cual se necesitó de: • 7 compuertas AND de 2 entradas • 9 compuertas AND de 3 entradas. • 1 compuerta AND de 4 entradas • 4 compuertas NOR(DM) de 3 entradas. • 3 compuertas NOR(DM) de 2 entradas. • 4 compuertas NAND de 2 entradas. • 4 inversores. 88 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL Figura 7.4: Estructura interna del 7449. DISEÑO CON VHDL A continuación se muestran los programas que definen el decodificador en VHDL, el primero es el decodificador de BCD a 7-segmentos, tal cual se ha descrito anteriormente. El segundo programa es una pequeña modificación para que visualice los códigos hexadecimales. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 library IEEE ; use IEEE . std_logic_1164 . all ; entity V74x49 is port ( BI : in std_logic ; A : in std_logic_vector (3 downto 0) ; Y : out std_logic_vector (0 to 6) ) ; end V74x49 ; architecture V74x49_B of V74x49 is signal Yi : std_logic_vector (0 to 6) ; begin with A select Yi <= -ABCDEFG " 1111110 " when " 0000 " , " 0110000 " when " 0001 " , " 1101101 " when " 0010 " , " 1111001 " when " 0011 " , 7.2. DECODIFICADOR BCD A 7-SEGMENTOS (7449) 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 " 0110011 " " 1011011 " " 0011111 " " 1110000 " " 1111111 " " 1110011 " " 0001101 " " 0011001 " " 0100011 " " 1001011 " " 0001111 " " 0000000 " " 0000000 " when when when when when when when when when when when when when " 0100 " , " 0101 " , " 0110 " , " 0111 " , " 1000 " , " 1001 " , " 1010 " , " 1011 " , " 1100 " , " 1101 " , " 1110 " , " 1111 " , others ; Y <= NOT Yi when ( NOT BI ) = ’1 ’ else " 0000000 " ; end V74x49_B ; 33 Listado 7.2: Decodificador BCD A 7-Segmentos 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 89 library IEEE ; use IEEE . std_logic_1164 . all ; entity HEX_TO_7SEG is port ( BI : in std_logic ; A : in std_logic_vector (3 downto 0) ; Y : out std_logic_vector (0 to 6) ) ; end HEX_TO_7SEG ; architecture HEX_TO_7SEG of HEX_TO_7SEG is signal Yi : std_logic_vector (0 to 6) ; begin process (A , BI , Yi ) begin case A is when " 0000 " when " 0001 " when " 0010 " when " 0011 " when " 0100 " when " 0101 " when " 0110 " when " 0111 " when " 1000 " when " 1001 " => => => => => => => => => => Yi Yi Yi Yi Yi Yi Yi Yi Yi Yi <= <= <= <= <= <= <= <= <= <= " 1111110 " ; " 0110000 " ; " 1101101 " ; " 1111001 " ; " 0110011 " ; " 1011011 " ; " 1011111 " ; " 1110000 " ; " 1111111 " ; " 1110011 " ; 90 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL Figura 7.5: Varios tipos de buffers de tercer estado. 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 when " 1010 " when " 1011 " when " 1100 " when " 1101 " when " 1110 " when " 1111 " when others end case ; => => => => => => => Yi Yi Yi Yi Yi Yi Yi <= <= <= <= <= <= <= " 1110111 " ; " 0011111 " ; " 1001110 " ; " 0111101 " ; " 1001111 " ; " 1000111 " ; " 0000000 " ; if ( not BI ) = ’1 ’ then Y <= not Yi ; else Y <= " 0000000 " ; end if ; end process ; end HEX_TO_7SEG ; Listado 7.3: Decodificador BCD A 7-Segmentos 7.3 Buffer de Tercer Estado DISEÑO TRADICIONAL. Los sı́mbolos lógicos de 4 tipos de buffers de tercer estado se observan a continuación: Los dos primeros buffers son no inversores y los últimos inversores. La señal extra ubicada en la parte superior del sı́mbolo es la entrada de habilitación del buffer de tercer estado. Esta puede ser activa alta o activa baja. Cuando el dispositivo está activado, se comporta como un buffer común o como inversor. Cuando el buffer no está activado, su salida va a un estado de alta impedancia, es decir se comporta como si el dispositivo estuviera desconectado. Los buffers de tercer estado permiten que múltiples fuentes compartan una lı́nea sin que haya superposición de señales. Un bus transceiver contiene pares de buffers de tercer estado conectados en direcciones opuestas entre cada par de pines, de tal manera que los datos pueden transferirse en cualquier dirección. Un ejemplo de transcerver octal de tercer estado es el 7.3. BUFFER DE TERCER ESTADO 91 Figura 7.6: Sı́mbolo lógico del 74x245. 74x245, que se observa en la figura 7.6. La entrada S/R determina la dirección de la transferencia, de A a B o de B a A. El buffer se habilita sólo si /CE se lleva a 0 lógico. La estructura interna del 74x245 se observa en la siguiente aplicación: DISEÑO CON VHDL. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 library IEEE ; use IEEE . std_logic_1164 . all ; entity V3statex is port ( G_L : in STD_LOGIC ; SEL : in STD_LOGIC_VECTOR (1 downto 0) ; A , B , C , D : in STD_LOGIC_VECTOR (1 to 8) ; X : out STD_LOGIC_VECTOR (1 to 8) ); end V3statex ; architecture V3states of V3statex is process ( G_L , SEL , A , B , C , D ) begin if G_L = ’0 ’ then if SEL = " 00 " then X <= A ; elsif SEL = " 01 " then X <= elsif SEL = " 10 " then X <= elsif SEL = " 11 " then X <= end if ; begin B; C; D; 92 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL Figura 7.7: Estructura interna del 72x245. 21 22 23 24 25 26 else X <= ( others = > ’Z ’) ; end if ; end process ; end V3states ; Listado 7.4: Buffer de tercer estado VHDL no tiene tipos y operadores para salidas de tercer estado, pero tiene primitivas que pueden ser usadas para crear señales y sistemas con posibilidad de tercer estado. Por ejemplo, el tipo std logic define ’Z’como uno de los 9 posibles valores que puede tomar una señal digital. Este valor se usa para el estado de alta impedancia. En el programa anterior se define un proceso, en el cual se emplean lazos if para evaluar el estado de la entrada de habilitación y para asignarle a la salida una de las diferentes entradas. 7.4 Multiplexor 8 a 1 DISEÑO TRADICIONAL. 7.4. MULTIPLEXOR 8 A 1 93 Entradas Salidas Selección Habilitador S2 S1 S0 E Y W X X X 1 0 1 0 0 0 0 D0 D0 0 0 1 0 D1 D1 0 1 0 0 D2 D2 0 1 1 0 D3 D3 1 0 0 0 D4 D4 1 0 1 0 D5 D5 1 1 0 0 D6 D6 1 1 1 0 D7 D7 Cuadro 7.3: Tabla de verdad del mux 8 a 1 Este multiplexor consta de ocho entradas de datos, tres entradas para selección, una entrada habilitadora y dos salidas, su funcionamiento es la de un switch digital el cual enruta uno de los varios datos de entrada a la salida dependiendo de las entradas de selección. Su tabla de verdad es como sigue. Para implementación de este circuito mediante compuertas, se necesitan: • 1 compuerta NOR de 8 entradas. • 8 compuertas AND de 5 entradas. • 7 inversores. En el esquema anterior se observan compuertas AND de cuatro entradas, esto es porque falta la entrada inversora que serı́a la quinta entrada para las compuertas AND. DISEÑO CON VHDL. Aquı́ utilizamos una estructura condicional para implementar el multiplexor, la cual es muy parecida a una tabla, asignando el dato de entrada correspondiente cuando se verifica la combinación de entrada de selección. 1 2 3 4 library IEEE ; use IEEE . std_logic_1164 . all ; entity v74x151 is port ( E : in std_logic ; 94 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL Figura 7.8: Estructura interna del mux 8 a 1. 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 Sel : in std_logic_vector (2 downto 0) ; D0 , D1 , D2 , D3 , D4 , D5 , D6 , D7 : in std_logic ; y , y_l : out std_logic ) ; end v74x151 ; architecture v74x151 of v74x151 is signal dato : std_logic ; begin with Sel select dato <= D0 when " 000 " , D1 when " 001 " , D2 when " 010 " , D3 when " 011 " , D4 when " 100 " , D5 when " 101 " , D6 when " 110 " , D7 when " 111 " , ’0 ’ when others ; y <= dato when E = ’1 ’ else ’0 ’; y_l <= not dato when E = ’1 ’ else ’0 ’; end v74x151 ; Listado 7.5: Multiplexor 8 a 1 7.5. MUTLIPLICADOR 95 Figura 7.9: Multiplicación. Figura 7.10: Sumador completo (full adder) de dos bits, esquema interno, sı́mbolo. 7.5 Mutliplicador DISEÑO TRADICIONAL. Una multiplicación combinacional se realiza basándose en el algoritmo de desplazamiento y suma. La multiplicación se realiza de forma similar a como se realizaba en la primaria, solo que más fácil, ya que se multiplica por uno (1) o por cero (0) y la suma se limita a contar unos (1). Hay varias maneras de implementar la multiplicación entre dos números de n bits, una de ellas es el diseño a partir de la tabla de verdad, la cual es viable cuandon es pequeña (n < 4). Cuando se requieren multiplicaciones con un número mayor de bits, se puede implementar el algoritmo de la primaria con la ayuda de compuertas AND, para los productos entre bits, y sumadores completos de dos bits. Con una adecuada interconexión se logra los resultados esperados. La implementación de un multiplicador 4 bits x 4 bits se muestra en la siguiente página. Como puede observarse, se requiere de 12 sumadores completos de dos bits, los cuales cada uno esta formado por dos compuertas EXOR de 2 entradas, tres compuertas AND de dos entradas y una compuerta OR de tres entradas, (como se muestra en la siguiente figura) y 16 compuertas AND de dos entradas. DISEÑO CON VHDL. Para la implementación de un multiplicar en VHDL, tenemos varias opciones, una de ellas podrı́a ser el empleo de la librerı́a del IEEE std logic arith, en la cual se puede ejecutar la operación entre dos palabras de n (hasta 16) bits con el empleo del 96 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL Figura 7.11: Multiplicador 4 bits x 4 bits. operador “*”. A continuación se muestra un archivo donde se realiza una operación entre dos palabras de seis bits, la razón por la cual se realizó de este tamaño de palabra es debido a la capacidad de la FPGA empleado. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 library ieee ; -- use ieee . std_logic_1164 . all ; use ieee . std_logic_arith . all ; entity mul_6x6 is port ( a , b : in unsigned (0 to 5) ; -- no se puede trabajar con m : out unsigned (0 to 11) -- std_logic_vector ); end mul_6x6 ; architecture mul_6x6 of mul_6x6 is begin m <= a * b ; end mul_6x6 ; Listado 7.6: Multiplicador Otra opción podrı́a ser la implementación del algoritmo de desplazamientos y sumas, 7.5. MUTLIPLICADOR 97 como se muestra a continuación. En el archivo fuente se destaca los procedimientos empleados: en la primera parte se definen los componentes AND2, XOR2 y MAJ, con los cuales se implementa el sumador completo (full adder), a continuación se generan los productos entre bits, luego se realizan las sumas parciales y último se “arma” o se genera el resultado final. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 library IEEE ; use IEEE . std_logic_1164 . all ; entity vmul8x8p is port ( X : in STD_LOGIC_VECTOR (7 downto 0) ; Y : in STD_LOGIC_VECTOR (7 downto 0) ; P : out STD_LOGIC_VECTOR (15 downto 0) ) ; end vmul8x8p ; architecture vmul8x8p_arch of vmul8x8p is function MAJ ( I1 , I2 , I3 : STD_LOGIC ) return STD_LOGIC is begin return (( I1 and I2 ) or ( I1 and I3 ) or ( I2 and I3 ) ) ; end MAJ ; begin process (X , Y ) type array8x8 is array (0 to 7) of STD_LOGIC_VECTOR (7 downto 0) ; variable PC : array8x8 ; -- producto de bits variable PCS : array8x8 ; -- bit suma del full - adder variable PCC : array8x8 ; -- bit carry del full - adder variable RAS , RAC : STD_LOGIC_VECTOR (7 downto 0) ; -- suma parcial begin -- carry y sumandos for i in 0 to 7 loop for j in 0 to 7 loop PC ( i ) ( j ) := Y ( i ) and X ( j ) ; -- realización de los productos de bits end loop ; end loop ; for j in 0 to 7 loop PCS (0) ( j ) := PC (0) ( j ) ; -- primera fila " virtual " PCC (0) ( j ) := ’0 ’; -end loop ; for i in 1 to 7 loop -- sumas parciales , excepto la última fila for j in 0 to 6 loop PCS ( i ) ( j ) := PC ( i ) ( j ) xor PCS (i -1) ( j +1) xor PCC (i -1) (j); PCC ( i ) ( j ) := MAJ ( PC ( i ) ( j ) , PCS (i -1) ( j +1) , PCC (i -1) ( j )); PCS ( i ) (7) := PC ( i ) (7) ; -- salida última suma " virtual " 98 CAPÍTULO 7. CIRCUITOS COMBINACIONALES EN VHDL 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 end loop ; end loop ; RAC (0) := ’0 ’; for i in 0 to 6 loop -- suma final RAS ( i ) := PCS (7) ( i +1) xor PCC (7) ( i ) xor RAC ( i ) ; RAC ( i +1) := MAJ ( PCS (7) ( i +1) , PCC (7) ( i ) , RAC ( i ) ) ; end loop ; for i in 0 to 7 loop P ( i ) <= PCS ( i ) (0) ; -- primeros 8 bits del producto , del full - adder end loop ; for i in 8 to 14 loop P ( i ) <= RAS (i -8) ; -- siguientes 7 bits del producto end loop ; P (15) <= RAC (7) ; -- último bit , carry del full adder end process ; end vmul8x8p_arch ; Listado 7.7: Multiplicador Para la implementación de la multiplicación se utilizó la librerı́a aritmética (ieee.std logic artih.all), la cual prácticamente resuelve el problema del diseño con el empleo de modelos ya predeterminados por el fabricante. Si se desea tener un control mayor sobre el diseño es recomendable o preferible crear las funciones o implementar los algoritmos que se cumplan con los requerimientos, y en este ejemplo se sigue esta tendencia. Capı́tulo 8 Introducción a los circuitos secuenciales Conceptos básicos El latch S-R Diagramas de tiempo Tablas caracterı́sticas El Flip-Flop Flip-Flops TTL Contador de rizado o asincrónico Contador módulo n División de frecuencia Modificación de la secuencia de conteo Contadores comercialmente disponibles Saber Hacer Entender el funcionamiento tanto del latch como del flip-flop. Saberlos diferenciar Construir cualquier contador asincrónico Construir divisores de frecuencia 99 100 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Figura 8.1: Latch S-R con compuertas NOR. 8.1 CIRCUITOS SECUENCIALES Los circuitos que hemos visto hasta ahora han sido combinacionales. La salida de un circuito combinacional es función solamente de las entradas. La salida de un circuito secuencial es función no solamente de las entradas sino también de la salida actual, es decir, se presenta retroalimentación. Los circuitos secuenciales forman la base de los registros, memorias y máquinas de estado, las cuales a su vez son unidades funcionales vitales en el diseño digital. 8.2 EL LATCH S- R El circuito secuencial más sencillo es el latch S-R. A partir de este circuito se construyen los flip-flops y a partir de los flips-flops, los registros, las memorias y las máquinas de estado que hemos mencionado. El latch S-R básico tiene dos entradas, S y R, y dos salidas, Q y Qque son siempre opuestas. La entrada S se usa para colocar (set) Q en 1; la entrada R se usa para borrar (Reset) Q a 0. En las figuras 8.1 y 8.2 se muestran dos implementaciones del latch S-R que usan las compuertas NOR y NAND respectivamente. Como puede verse, la implementación NOR tiene entradas activas altas. Esto indica que la operación Set o Reset se ejecuta bajando temporalmente la lı́nea Set o Reset a 0. Debido a la realimentación de las entradas, la salida permanecerá en 1 o en 0 aún después de que la señal “set” o “reset” haya desaparecido, con lo cual tendremos la capacidad de memoria del latch. Se encarece al lector verificar esto examinando las secuencias de la entrada mostradas en las figuras 8.3 y 8.4 y determinando las salidas de cada compuerta 8.2. EL LATCH S- R 101 Figura 8.2: Latch S-R con compuertas NAND. Figura 8.3: Diagrama de tiempos del latch S-R con compuertas NOR. del latch. Describir el comportamiento de los circuitos secuenciales es difı́cil. Existen varios métodos para descubrir la naturaleza de un circuito secuencial, incluyendo los diagramas de estado, las tablas de estado, las tablas de transición, las tablas caracterı́sticas y los diagramas de tiempo. En este capı́tulo veremos dos métodos: diagrama de tiempos simples y tablas de caracterı́sticas reducidas. Figura 8.4: Diagrama de tiempo del latch S-R de compuertas NAND. 102 8.2.1. CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Diagramas de Tiempo Los diagramas de tiempo constituyen la descripción más exacta de la operación del circuito. En las figuras 8.3 y 8.4 se observan los diagramas de tiempo que muestran el comportamiento de las implementaciones NOR y NAND del latch S-R. El eje vertical es voltaje e indica el estado de la lı́nea en 0 o en 1. El eje horizontal es el tiempo e indica la secuencia de los cambios de voltaje. En la figura 8.3 se ilustra el comportamiento de la implantación NOR. Al examinar de izquierda a derecha, vemos un estado inicial con Q, R, y S iguales todos a 0. La lı́nea “Set” se sube a 1. Esto coloca a Q en 1, aún cuando S regrese a 0. Finalmente, R se coloca en 1; esto restaura Q a 0, en donde permanece aún después de que R vuelve a 0. Los diagramas de tiempo mostrados en las figuras 8.3 y 8.4 son expresiones simplificadas de los diagramas de tiempo mostrados en los catálogos de los fabricantes. Los diagramas que hemos incluido simplemente ilustran la función del circuito, no la temporización detallada de los elementos electrónicos. Por ejemplo, las transiciones de estado mostradas verdaderamente tomarán tiempo, es decir, las transiciones no son verticales. Además, desde la transición de la lı́nea S-R hasta que la salida realmente cambia de estado, toma tiempo. Puesto que estos tiempos son muy cortos y ya que estamos interesados primordialmente en la función de la unidad y no en las caracterı́sticas de temporización electrónica, usaremos los diagramas de tiempo simplificados. 8.2.2. Tablas Caracterı́sticas Aun cuando el diagrama de tiempo ilustra exactamente el comportamiento de un circuito, es bastante complejo leerlo y no es muy compacto. Hasta ahora, hemos usado las tablas de verdad para ilustrar el comportamiento de los circuitos combinacionales. Para mostrar el comportamiento de los circuitos secuenciales, se puede usar una versión ligeramente modificada de las tablas de verdad llamada “tabla reducida de caracterı́sticas”. En las tablas 8.1 y 8.2 se muestran las tablas de caracterı́sticas para las implementaciones NOR y NAND del latch S-R. La tabla responde a la pregunta: ¿Cuál será el nuevo estado de las salidas si las entradas se colocan en estos valores? El estado actual de la salida se denomina Q. El siguiente estado, es decir, el resultante de efectuar las transiciones provocadas por las entradas, se denomina Q+. Por ejemplo, en la primera lı́nea de la tabla podemos ver que si ambas entradas están en 0, la nueva salida “Q+” será “Q”, es decir, la salida permanece como estaba. De la tercera lı́nea vemos que si “S” se coloca en 1, el nuevo estado de la salida “Q+” será 1. Si “S” regresa a 0, la lı́nea 1 de la tabla nos dice que la nueva salida “Q+” será igual que como estaba; en este caso, si “Q” era 1, continuará en 1. 8.3. LATCHES SINCRÓNICOS (FLIP-FLOPS) S R Q+ 0 0 Q 0 1 0 1 0 1 1 1 - No cambia Condición inválida 103 Cuadro 8.1: Tabla caracterı́stica del latch S-R tipo NOR S R Q+ 0 0 - 0 1 1 1 0 0 1 1 Q Condición inválida No cambia Cuadro 8.2: Tabla caracterı́stica del latch S-R de compuertas NAND 8.3 LATCHES SINCRÓNICOS (FLIP-FLOPS) La salida del latch S-R se transformará en el mismo instante en que la entrada genere un cambio. A esto lo denominamos funcionamiento asincrónico. Pero en la mayorı́a de los circuitos digitales, la temporización de los eventos es crı́tica. Generalmente se utiliza un reloj para sincronizar la operación de las diferentes unidades funcionales del circuito. Para trabajar en este ambiente, el latch sólo debe cambiar de estado cuando la señal del reloj ası́ lo indique. A esto lo denominamos “funcionamiento sincrónico”. Los latches modificados para operar sincrónicamente, se denominan flip-flops. 8.3.1. Latches controlados por Compuertas Para lograr la operación sincrónica, el latch debe cambiar de estado solamente bajo la señal apropiada del reloj. Por ejemplo, supongamos que el latch debe cambiar de estado sólo cuando la señal de reloj sube. La manera más sencilla de lograr esto es agregando una compuerta a las entradas que le permita al latch “mirar” a las entradas solamente cuando el reloj esté en alto. A esto lo denominamos “latch controlado por compuertas” y se ilustra en la figura 8.5. Las dos compuertas NAND de la izquierda forman la compuerta de control y las dos compuertas NAND de la derecha forman el latch. Mientras la entrada del reloj (C) esté baja, la salida de la compuerta será siempre 1 sin importar el valor de S o R. Cuando el reloj (C) pase a alto, entonces las entradas S y R se pasan al latch y la salida cambia. El comportamiento de este circuito se muestra en la tabla 8.3 104 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Figura 8.5: Cerrojo con compuerta. C S R Q+ 0 0 0 Q 0 0 1 Q 0 1 0 Q 0 1 1 Q 1 0 0 Q 1 0 1 0 1 1 0 1 1 1 1 - Salida inmodificable mientras C sea igual a 0 (cero). No hay cambio Condición inválida Cuadro 8.3: Tabla caracterı́stica del latch S-R de compuertas NAND Existe un pequeño problema con esta solución. Durante el tiempo en que el reloj está alto, el latch controlado por la compuerta se comporta idénticamente al latch asincrónico corriente. Por lo tanto, si la entrada cambia varias veces, también cambiará varias veces el estado del latch. El problema se ilustra con el diagrama de tiempo de la figura 8.6 El primer ciclo del reloj, es “normal”. En éste, la lı́nea “S” está alta y “Q” sube también tan pronto como el reloj sube. El segundo ciclo del reloj ilustra el problema. Primero sube la lı́nea “R”, y “Q” cae a 0 tan pronto como el reloj sube. Pero mientras el reloj está aún alto, la lı́nea “S” sube y por lo tanto, “Q” vuelve nuevamente a 1 durante el mismo ciclo del reloj. 8.3.2. Flip-Flops disparados por Flanco La solución más común al problema es el flip-flop disparado por flanco. En un flip-flop disparado por flanco delantero, las entradas se miran solamente en el flanco del reloj que 8.3. LATCHES SINCRÓNICOS (FLIP-FLOPS) 105 Figura 8.6: Diagrama de tiempo del cerrojo con compuerta. Figura 8.7: Flip-Flop disparado por flanco. sube. En un flip-flop disparado por flanco trasero, las entradas se miran en el flanco del reloj que baja. El flip-flop disparado por flanco puede construirse fácilmente a partir del latch controlado por las compuertas. Hay que agregar un circuito de estrechamiento del pulso antes de la compuerta de entrada de modo que la compuerta esté activa solamente un instante en el flanco del reloj que baja o sube. Esta implementación se muestra en la figura 8.7. Nótese que se han agregado dos entradas, “Borrar” y “Preactivar”. Puesto que estas entradas van directamente al latch, pueden activar o borrar la salida independiente del reloj. Se les denomina “entradas asincrónicas” y son útiles para colocar el flip-flop en un estado inicial. Existen varias maneras de implementar el circuito de estrechamiento del pulso que ya hemos mencionado. En la Figura 8.8 se muestra una implementación sencilla. Este método se vale del hecho de que una compuerta realmente toma tiempo en cambiar de estado. Supongamos un estado inicial con la entrada baja del reloj. Debido al inversor de entrada, las entradas A y B en la compuerta NAND serán opuestas; la salida de la compuerta NAND será 1 y la salida final será 0. Cuando el reloj sube, la entrada B de la compuerta AND inmediatamente sube, pero la entrada A también permanece en alto hasta que el inversor cambia de alto a bajo. Esto toma aproximadamente 10ns con TTL estándar. Por lo tanto, durante 10ns, ambas entradas de la compuerta NAND están altas, la salida de la compuerta NAND está baja y la salida del circuito está alta. Después de 10ns, el inversor 106 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Figura 8.8: Circuito de estrechamiento de pulso. Figura 8.9: Flip-Flop Maestro-Esclavo. de entrada produce una salida baja, la cual a su vez cambia la salida de la compuerta NAND a 1 y la salida final retorna a 0. 8.3.3. Flip-Flop Maestro-Esclavo Otra técnica para eliminar las transiciones de estado múltiple que pueden ocurrir en un solo pulso de reloj, es el uso de una disposición maestro-esclavo. Un flip-flop maestroesclavo se forma de dos latches controlados por la compuerta, según se muestra en la figura 8.9. El latch de la izquierda o maestro forma las entradas al flip-flop y el de la derecha o esclavo forma las salidas del flip-flop. El latch maestro mira las entradas mientras el reloj está alto. Cuando el reloj baja, el esclavo queda habilitado, para utilizar las salidas del latch maestro como entradas. Por lo tanto, se “leen” las entradas mientras el reloj está alto y se transfieren a las salidas cuando el reloj retorna a cero. 8.4 FLIP-FLOPS TTL No es necesario construir flip-flops partiendo de las compuertas individuales puesto que existen muchas variaciones en los chips estándar TTL. Generalmente se encuentran de dos a ocho flip-flops en un solo integrado. Los más populares serán tratados en las siguientes secciones. 8.5. FLIP FLOPS J-K 8.5 107 Flip Flops J-K El flip-flop J-K es simplemente un flip-flop S-R que ha sido modificado de manera que ambas entradas se puedan activar el mismo tiempo. Mientras que esta condición fue invalidada para el flip-flop S-R, en el flip-flop JK esta condición conmuta la salida. En la Figura 8.10 se muestra el comportamiento descrito y la representación estándar del flip-flop J-K. J K Q+ 0 0 Q No cambia 0 1 0 Reset 1 0 1 Set 1 1 Q Conmuta Figura 8.10: El Flip-Flop J-K. El flip-flop JK está disponible en varios CHIPS TTL con varias opciones. Por ejemplo, el 7473 contiene dos flip-flops J-K con una entrada asincrónica de borrado, tal como se mencionó previamente. El 7476 contiene dos flip flops J-K con borrado y pre-activación. 8.5.1. Flip-Flops D El flip-flop D o flip-flop de datos sólo tiene una entrada de control, D. La salida del flip-flop se coloca en el valor que traiga D en cada ciclo del reloj. En la figura 8.11 se da a conocer el comportamiento descrito y la representación estándar del flip-flop D. D Q+ 0 0 1 1 Figura 8.11: El Flip-Flop D. 8.5.2. El flip-flop T El flip-flop T tiene sólo una entrada de control, T. Si la entrada es 1, la salida se conmuta y si es cero, la salida no cambia. El flip-flop T se construye a partir del J-K uniendo las dos entradas. 108 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES T Q+ 0 Q 1 Q Figura 8.12: El Flip-Flop T. Figura 8.13: Diagrama de tiempo de un contador. 8.6 CONTADORES 8.6.1. DEFINICIÓN En términos generales, un contador es un circuito secuencial que pasa por un conjunto dado de estados en ciclos sucesivos del reloj. Generalmente son estados secuenciales binarios (por ejemplo, 0 a 7, 0 a 15, etc.) y de donde resulta el término contador. Un estado es simplemente el valor binario representado por las salidas del contador. Por ejemplo, un contador de 0 a 15 requiere 4 salidas para representar los 4 bits. Los contadores son útiles en muchas aplicaciones: temporización, multiplexación y por supuesto, conteo. En este capı́tulo estudiamos el diseño y la aplicación de los contadores, incluyendo los comercialmente disponibles. 8.6.2. CONTADORES DE RIZADO ASINCRÓNICOS Si un flip-flop J-K se usa como flip-flop T (uniendo J y K), la salida cambia de estado en cada ciclo del reloj. Por tanto, después de 2 ciclos del reloj, la salida del flip-flop completa un ciclo. Si la salida de este flip-flop es utilizada como entrada a un segundo flip-flop T, la salida del segundo flip-flop oscilará con la mitad de la velocidad del primer flip-flop. Cada flop-flip adicional agregado de esta manera, oscilará con la mitad de la velocidad del flip-flop precedente. El comportamiento para los dos flip-flops es ilustrado en el diagrama de tiempo mostrado en la figura 8.13. Considerando la salida del primer flip-flop, Qa como el primer dı́gito y la salida del segundo flip-flop como el segundo dı́gito, se obtiene un contador binario sencillo que va 8.6. CONTADORES 109 Figura 8.14: Contador de 2 bits. desde 0 hasta 3 y luego repite. En la Figura 36 se muestra un circuito para implementar este contador. La ausencia de conexiones a las entradas J y K indica que se conecta a “alto”. Puede lograrse un contador de 0 a 7 agregando un flip-flop adicional (3 en total). De 0 a 15 podemos contar con 4 flip-flops y ası́ sucesivamente. Nótese en el diagrama de tiempo de la figura 8.13, que los cambios de estado ocurren en el lado descendente del reloj. Recuerde que en la práctica de laboratorio del capı́tulo 5 el flip-flop J-K 7476 también cambia de estado en el lado descendente del reloj. Estos flip-flops son bastante apropiados para hacer contadores. En el diagrama de tiempo las transiciones de estado ocurren exactamente en el lado descendente del reloj. Como se mencionó en el capı́tulo 5, esto no es totalmente cierto; toma tiempo desde el lado descendente del pulso hasta que la salida del flip-flop cambia de estado. Para el flip-flop 7476 el retardo es de aproximadamente 40ns. Para el contador de rizado de 2 bits de la figura 8.14 el primer dı́gito (Qa) cambia 40ns después del lado descendente del reloj. Dado que Qa es la entrada de reloj para el segundo flip-flop, el segundo dı́gito (Qb) cambia 40ns después del eje descendente de Qa y 80ns después del pulso del reloj original. Con cada flip-flop adicional se agrega una demora de 40ns a medida que la señal de reloj “se propaga” a través de la cadena de flip-flops. Dado que cada flip-flop no cambia de estado por una señal común, no se considera un dispositivo sincrónico. Si se unen estas observaciones, se verá el porqué del nombre “contador de rizado asincrónico”, para los que abreviadamente se denominan contadores de rizado. Consideraciones de Tiempo La velocidad máxima que puede alcanzar un contador de rizado depende de la demora de la conmutación de los flip-flops usados y del número de flip-flops del contador. Por ejemplo, consideremos un contador de rizado de 4 bits que use flip-flops J-K 7476. La demora más larga ocurre cuando todos los cuatro flip-flops desde el menos significativo (Qa) hasta el más significativo (Qd), deben cambiar de estado. Esto ocurre cuando hay que cambiar desde el estado 7 (0111) al estado 8 (1000) o al cambiar del estado 15 (1111) al estado 0 (0000). Puesto que cada flip-flop introduce un retardo de 40ns, la demora total para cambiar de un estado a otro y la máxima rata de conteo resultante, son: 110 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Figura 8.15: Cambio del estado 15 al estado 0 Maxima demora de conmutacion= 4 × 40ns = 160ns Maxima rata deconteo= 1/160ns = 6,25M Hz El valor para la rata máxima de conteo asume que cada estado existe durante algún tiempo corto antes del siguiente pulso de reloj. El lı́mite práctico es menor puesto que a esta velocidad los estados 0 y 8 existirán durante ese periodo. El diagrama de tiempo de la figura 8.15 muestra el retardo de conmutación que ocurre cuando se pasa del estado 15 al estado 0. Los estados de salida de un contador se usan a menudo como entradas de control a los multiplexores, decodificadores, memorias, etc. El estado puede representar una posición de memoria que se va a leer o una salida del decodificador que se va a colocar en 0 pero con un contador de rizado, la transición de un estado a otro no es instantánea. La figura 8.15 muestra la secuencia de transición de los flip-flops cuando un contador de rizado cambia del estado 15 (1111) al estado 0 (0000). En el lado descendente del reloj, el estado de salida es 15 (1111). Cuarenta n segundos más tarde, Qa cae a 0 y cambia la salida a 14 (1110). Cuarenta ns después de Qa , Qb cae a 0 y deja la salida en 12 (1100). Qc cae a 0 40 ns después de Qb y deja la salida en 8 (1100) y finalmente Qd cae a 0 40ns, después de Qc , 160ns después del lado original del reloj, con la salida ahora en 0. De manera que al cambiar el contador del estado 15 al estado 0, los estados 14, 12 y 8 existen durante 40ns cada uno. Estos estados intermedios son llamados “ruidos” o “impulsos de decodificación”. Los ruidos no solamente se presentan al cambiar del estado 15 al 0. En cualquier momento en que más de un flip-flop debe cambiar de estado, existirán estados intermedios. Para ilustrar el efecto de estos ruidos considérese un contador que tenga que manejar las lı́neas de selección de un decodificador de 0 a 15. Las salidas del decodificador pueden estar encendiendo uno de los 16 valores de un despliegue de siete segmentos. Pero como ya se mencionó, cuando se conmuta del estado 15 al estado 0, existirán los estados 14,12 8.6. CONTADORES 111 y 8 durante 40ns. Por tanto, en esta aplicación, los despliegues 14, 12 y 8 se encenderán durante 40ns cuando se requiere el cambio de 15 a 0. Por supuesto, un parpadeo 40ns no es muy evidente para el ojo humano pero si la salida del decodificador está siendo tomada por otro aparato digital, 40ns puede ser mucho tiempo. 8.6.3. GENERACIÓN DE SEÑALES DE RELOJ CON CONTADORES DE RIZADO Un contador de rizado se puede usar para dividir la frecuencia de una señal de reloj. Por ejemplo, suponga que un circuito digital tiene un reloj de 10KHz. Además de la señal de 10KHz, el circuito también requiere un reloj de 5KHz. En lugar de tener circuitos de reloj separados para cada una de estas frecuencias, podemos obtener el reloj de 5KHz dividiendo por 2 la señal de 10KHz. Recordemos de la sección ?? que la salida de un flip-flop T oscila con la mitad de la frecuencia del reloj de entrada. Por tanto, un contador de 1 bit ejecuta una operación de división por 2. Igualmente, si añadimos un segundo flip-flop T, éste oscilará con la mitad de la frecuencia del primero y con un cuarto de la frecuencia original. Por tanto, un contador de rizado de 2 bits ejecuta una operación de división por 4. La operación “dividir por n” que ejecuta el contador es igual al número de estados en la secuencia del contador. Un contador de 2 bits tiene 4 estados, 0 a 3 y ejecuta una operación de división por 4. De igual manera, un contador de 3 bits tiene 8 estados y ejecuta una operación de división por 8. Modificación de la Secuencia de conteo El número de estados en la secuencia de un contador de rizado ha sido hasta ahora una potencia de 2. Cómo podrı́amos dividir una señal de reloj por algún otro valor que no sea potencia de 2, 5 por ejemplo? Obviamente para dividir por 5, el contador debe tener 5 estados. Para hacer esto, se usa un contador de rizado común al cual se le agregan compuertas adicionales para obligarlo a volver a 0 después de 5 estados. En este caso, el contador pasará por 0, 1, 2, 3, 4 y luego repetirá. Recordemos, la presencia de entradas de borrado asincrónico en el flip-flop J-K 7476. Usando estas entradas, el contador se puede volver a 0 cuando sea necesario. En el ejemplo anterior se vuelve a 0 cuando el contador intenta pasar al estado 5. En la figura ?? se muestra el contador de división por 5. Como se puede ver, la compuerta NAND detecta el estado 5 cuando Qc y Qa son ambos 1. En este momento, la compuerta NAND se acciona y hace volver los contadores al estado 0. La operación se muestra en el diagrama de tiempo de la figura 8.17. 40ns después del vértice descendente del reloj, Qa pasa a 1 y el contador queda en estado 5. Al llegar al estado 5, ambas entradas de la compuerta NAND valen 1 y 10ns después (el retardo de la compuerta NAND), la salida de la compuerta NAND pasa a 0 para borrar 112 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Figura 8.16: Contador de división por 5. Figura 8.17: Cambio del estado 4 al estado 0. los flip-flops; la operación de borrado de un flip-flop J-K 7476 toma un máximo de 40ns. Finalmente, la salida se borra 90ns después del vértice descendente del reloj. Nótese que el estado 5 existe durante 50ns pero mirando la figura 8.17, puede verse que el estado intermedio no afecta a Qc . Generación de una onda simétrica La onda cuadrada resultante del contador divisor por 5 descrito anteriormente no es simétrica: vale 0 durante 4 ciclos del reloj de entrada (000 a 011) y 1 para un ciclo del reloj de entrada (100). La figura 8.18 muestra el reloj de entrada y la salida tomada de Qc . Los números en la parte inferior, indican el estado actual del contador después de cada transición. No se muestran los retardos por conmutación. Algunas aplicaciones requieren una onda más simétrica: una onda que valga 1 y la misma cantidad de tiempo que valga 0. Obviamente que esto es imposible cuando se divide el reloj por un valor impar pero puede obtenerse una onda más simétrica si se toma la salida de la salida de un contador diferente. A continuación se muestra la secuencia de los estados del contador divisor por 5 descrito previamente. 8.6. CONTADORES 113 Figura 8.18: Salida del divisor por 5. Qc Qb Qa 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 0 .. . 0 .. . 0 .. . (fin del ciclo) Como puede verse, Qc cambia una vez durante la secuencia pero Qb también hace .lo mismo por lo cual se puede tomar como salida. Adicionalmente, Qb es más simétrica: vale 0 durante 3 ciclos y 1 durante 2 ciclos. Es importante que la salida del contador usado como salida de reloj, no esté afectada por los ruidos. Por ejemplo, en la secuencia previa, Qa aparentemente permanece en 0 entre el estado 4 y el estado 0. Pero según se muestra en la figura 8.17, Qa va temporalmente a 1 cuando se cambia de estado 4 al estado 0. Si se usara Qa como reloj, este corto perı́odo de 40ns podrı́a ocasionar problemas. Si la longitud de la secuencia deseada es par, se puede generar una onda completamente simétrica. Una operación de división por 2 siempre produce una onda simétrica. Si se descompone una operación de división par en dos operaciones de división en donde la última es de división por 2, se producirá una onda simétrica. Por ejemplo, una operación de división por 10 puede ejecutarse dividiendo por 5 y luego por 2. La figura 8.19 muestra un contador divisor por 6 simétrico. Los dos flip-flops de la derecha forman el contador divisor por 3. Nótese que la compuerta NAND borra el contador al cambiar de 2 a 3. El flip-flop de la izquierda es el divisor por 2, de donde se toma la salida. 114 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Figura 8.19: Contador divisor por 6 simétrico. 8.6.4. OTRAS APLICACIONES DE LOS CONTADORES La generación de señales de reloj ciertamente no es la única aplicación de los contadores. Los contadores se usan en muchas aplicaciones, incluyendo multiplexamiento, temporización y conteo de pulsos, medición de frecuencia y convertidores análogo-digitales. En aplicaciones de multiplexación, el contador generalmente se utiliza para suministrar la secuencia de selección de lı́nea para el multiplexor o el decodificador. El efecto de los ruidos, debe considerarse cuidadosamente en éstas aplicaciones, especialmente cuando se emplea multiplexación para pasar datos a otros aparatos digitales. Un contador fácilmente puede arrancarse y luego detenerse por medio de dos pulsos de entrada consecutivos. Si el contador se alimenta con un reloj de frecuencia conocida entre los pulsos, se puede determinar el tiempo entre ellos. En esta aplicación, las consideraciones primarias de diseño son el número de bits del contador y la velocidad máxima de conteo. Un contador puede también contar pulsos. En esta aplicación, se usan los pulsos como el reloj del contador. Contando sobre un perı́odo dado de tiempo, se puede determinar la frecuencia promedio de los pulsos. En este caso, las consideraciones primarias son nuevamente el número de bits y la velocidad máxima de conteo. Un convertidor análogo-digital convierte un voltaje de entrada en un valor binario que representa ese voltaje. Por ejemplo, un convertidor A/D de 8 bits puede usarse para transformar un voltaje entre 0 y 5 voltios en un valor binario entre 0 y 255. Los convertidores A/D pueden hacerse de diversas maneras y varios de esos métodos usan contadores. Por ejemplo, un método simple usa las salidas de un contador para alimentar las entradas de un convertidor digital a análogo. Para cada salida del contador, el convertidor D/A producirá un voltaje diferente. Un dispositivo llamado comparador se utiliza para determinar cuándo es mayor la salida del convertidor D/A que el voltaje de entrada. Cuando ocurra, el contador se detiene y el valor que esté en el contador representa el valor binario del voltaje de entrada. 8.6. CONTADORES 8.6.5. 115 CONTADORES DE RIZADO COMERCIALMENTE DISPONIBLES Rara vez es necesario construir contadores partiendo de flip-flops individuales, puesto que existen varios contadores disponibles en chips. Por ejemplo, el 7493 es un contador de rizado de 4 bits que usa flip-flops J-K. Tres de los flip-flops están conectados internamente como un contador de rizado de 3 bits. Un cuarto flip-flop tiene entrada de reloj separada y su salida no está conectada al otro flip-flop. Para usar el chip como contador de 3 bits, se le suministra la señal de reloj a la entrada de reloj del contador de 3 bits. Para usar el chip como contador de 4 bits, se conecta la salida del flip-flop sencillo a la entrada de reloj del contador de 3 bits y se le suministra la señal de reloj al flip-flop sencillo. Una lı́nea común de borrado pasa por todos los flip-flops pero en lugar de existir simplemente una señal de borrado activa-baja tal como en flip-flop 7476, la operación de borrado es activada por una compuerta NAND de dos entradas. Para borrar el contador, ambas entradas deben valer 1. Nótese en la figura 8.18 que ası́ fue como se modificó la secuencia de conteo de un contador de rizado de 3 bits para obtener un contador divisor por 5. El contador divisor por 5 puede implementarse fácilmente con el chip 7493, mientras que sin éste necesitarı́amos dos chips 7476 y un chip 7400. Otros contadores tienen diferentes secuencias de conteo. El 7490 es un contador de décadas. Tiene 10 estados del 0 al 9 y es muy útil en operaciones de conteo decimal. Igual que el 7493, está dividido en un contador de 3 bits y un flip-flop separado. Usando el contador de 3 bits, el 7490 ejecuta una operación de división por 5. Existen otros contadores: el 7492 es un contador divisor por 12 o divisor por 6. El 74163 es un contador binario de 4 bits sincrónico. En un contador sincrónico, todas las salidas cambian de estado al mismo tiempo. Se estudiará el diseño de contadores sincrónicos y de secuenciadores de estado que no necesariamente cuentan secuencialmente. 116 CAPÍTULO 8. INTRODUCCIÓN A LOS CIRCUITOS SECUENCIALES Capı́tulo 9 Secuenciadores de Estado y Controladores Conceptos básicos Diagrama de estado Tabla de Transición Contador sincrónico Secuenciador Implementación de un secuenciador Saber Hacer Distinguir entre contadores sincrónicos y asincrónicos Construir un diagrama de estados de un proceso Implementarlo con flip-flops o con circuitos programables 117 118 9.1 CAPÍTULO 9. SECUENCIADORES DE ESTADO Y CONTROLADORES DEFINICIÓN En el Capı́tulo anterior vimos varias formas en las cuales los contadores pueden ser usados para controlar circuitos digitales auque muchas veces los requerimientos de control van más allá de la simple secuencia ascendente de estados que produce un contador. Los circuitos secuenciales que pueden generar cualquier secuencia especı́fica de estados son denominados secuenciadores de estado o controladores. A diferencia de los contadores de rizado, los secuenciadores de estado generalmente son sincrónicos, es decir, todas las salidas cambian al mismo tiempo, basadas en un reloj común. Obviamente un secuenciador de estado que genere una secuencia ascendente de estados es simplemente un contador sincrónico pero con la capacidad de generar otras secuencias de estados, los secuenciadores pueden producir una secuencia de control más compleja. La salida de un secuenciador a menudo se divide en campos de varios tamaños y cada campo está destinado a controlar una operación que debe ocurrir. En un procesador aritmético sencillo, por ejemplo, los campos individuales podrı́an controlar el cargue de los registros, el enrutamiento de los datos a través de lı́neas de selección en un multiplexor, la selección de función en una unidad aritmética, etc. Como ayuda en el diseño de estos elementos, se introducen dos métodos para ilustrar el comportamiento de los circuitos secuenciales: el diagrama de estados y la tabla de transiciones. 9.1.1. Diagramas de estado Un diagrama de estado es una representación visual del comportamiento del circuito secuencial; es un gráfico dirigido en el cual los nodos indican los estados posibles de salida y las flechas representan las transiciones de estados válidas. A menudo las flechas llevan escritas las condiciones de entrada que provocan esa transición. 9.1.2. Tablas de transición Una tabla de transición enumera todas las posibles transiciones de estado y las entradas necesarias para producir cada cambio. La Tabla 9.1 es una tabla de transición para un flip flop J K. La segunda lı́nea, por ejemplo, muestra que para cambiar de 0 a 1, J debe estar en 1 y K puede estar en 0 o en 1. 9.2 CONTADORES SINCRÓNICOS Como se describió en el Capı́tulo anterior, los contadores de rizado tienen muchos usos. Sin embargo, en algunas aplicaciones los impulsos causados por la naturaleza asincrónica del contador pueden ocasionar problemas. En un contador sincrónico, todos los flip flops cambian de estado a partir de una señal de reloj común. Por tanto, todos los flip flops cambian de estado al mismo tiempo y en consecuencia no existen los impulsos o saltos. 9.2. CONTADORES SINCRÓNICOS Estado Actual 119 Próximo Estado Entrada Entrada Q Q0 J K 0 0 0 X 0 1 1 X 1 0 X 1 1 1 X 0 Cuadro 9.1: Tabla de transición de un flip flop J-K Supongamos que se necesita un contador binario de 3 bits. Para diseñar un contador sincrónico se empieza empezamos con un flip flop por cada bit, como en el contador de rizado. Pero en lugar de obtener la entrada de reloj del flip flop anterior, se conecta la señal de reloj a todos los flip flops y se le agrega una lógica sencilla para generar la secuencia apropiada. La tabla 9.2 muestra la secuencia de transiciones de estado y las entradas J K necesarias. Por cada estado actual existe un conjunto diferente de entradas J K requeridas para ejecutar apropiadamente la transición al siguiente estado. Por tanto, las entradas J K se pueden pensar como funciones del estado actual, es decir, de Qc , Qb y Qa . De esta manera, se derivan las expresiones booleanas para cada entrada J, K como función de Qc , Qb y Qa . EstadoActualEstadoPróximoEntradas necesarias par producir cambio Qc Qb Qa Qc Qb Qa Jc Kc Jb Kb Ja Ka 0 0 0 0 0 1 0 X 0 X 1 X 0 0 1 0 1 0 0 X 1 XX 1 0 1 0 0 1 1 0 XX 0 1 X 0 1 1 1 0 0 1 XX 1 X 1 1 0 0 1 0 1 X 0 0 X 1 X 1 0 1 1 1 0 X 0 1 XX 1 1 1 0 1 1 1 X 0 X 0 1 X 1 1 1 0 0 0 X 1 X 1 X 1 Cuadro 9.2: Tabla de transiciones para un contador de tres bits. En la Figura 9.1 están los mapas K y las ecuaciones para cada una de las entradas J K. En la Figura 9.2 está el diagrama lógico que implementa este secuenciador. 120 CAPÍTULO 9. SECUENCIADORES DE ESTADO Y CONTROLADORES @ Qb Qa Qc @ 00 01 11 @ 0 0 0 0 1 @ Qb Qa Qc @ 00 10 1 1 3 X X 4 0 0 0 X 1 X X 1 0 5 Jc = Qb Qa @ Qb Qa Qc @ 00 01 0 1 0 0 1 0 $ 3 1 @ Qb Qa Qc @ 00 @ 0 X 2 X 5 7 & 4 10 X 1 X 6 % 01 X 0 01 1 0 11 10 $ 1 X 1 1 X 1 3 X 1 X 11 10 $ 1 X 1 4 3 1 X 0 2 5 7 & 7 @ Qb Qa Qc @ 00 0 6 % 0 % 11 10 $ 1 1 X 0 X 6 01 @' 2 X 4 5 & 0 Kb = Qa @' 0 1 7 6 ' Jb = Qa @ Qb Qa Qc @ 00 X 2 Kc = Qb Qa 11 ' @ 10 X 3 0 4 11 X 2 7 6 5 01 @ 1 X 1 4 5 & Ja = 1 1 3 1 7 Ka = 1 Figura 9.1: Mapas K y ecuaciones J K. Figura 9.2: Contador sincrónico de tres bits. X 2 X 6 % 9.3. SECUENCIADORES DE ESTADO 9.2.1. 121 Contadores sincrónicos comercialmente disponibles Existen varias modalidades de contadores sincrónicos disponibles en chips TTL. Muchos de estos pueden ser cargados paralelamente para empezar el contador con un valor especı́fico. Algunos contadores tienen entradas de control que permiten la selección de la secuencia de conteo ascendente o descendente. El 74161 y el 74163 son contadores sincrónicos de 4 bits. A diferencia del contador de rizado de 4 bits 7493, estos contadores cambian de estado en el flanco delantero del reloj de entrada en lugar del flanco posterior. El 74161 tiene una entrada de borrado asincrónico que puede ser usada para modificar la longitud del conteo de manera similar a la ilustrada en el Capı́tulo ?? para contadores de rizado. Desafortunadamente esta técnica también produce impulsos con los contadores sincrónicos en forma similar a la de los contadores sincrónicos. Para evitar este problema, el 74163 tiene una entrada de borrado sincrónico, la cual borra el contador hasta la próxima señal de reloj que sigue a la activación de la señal. Por ejemplo, suponga que se ha agregado lógica de modo que se active la señal de borrado cuando se llegue al estado 4. Aunque la señal de borrado se activa un instante después de cambiar al estado 4, la operación de borrado no ocurrirá sino hasta que se presente el siguiente flanco delantero del reloj. Para ilustrar el uso de este borrado sincrónico, suponga que se necesita un contador divisor por 5. Este contador tiene 5 estados, desde 0 hasta 4. Como se vio en el Capı́tulo 8, la secuencia de conteo debe modificarse de modo que el contador pase del estado 4 al estado 0 en lugar de pasar del estado 4 al estado 5. El método estudiado en el Capı́tulo 8 utilizó la entrada de borrado asincrónico para borrar el contador en el instante que cambiaba al estado 5. La breve existencia del estado 5 es por supuesto, un salto o un impulso. Con la entrada del borrado sincrónico, la señal se activa al llegar al estado 4 y la operación tiene lugar cuando se presente el próximo pulso de reloj. En este pulso, el contador es borrado en lugar de cambiar a 5. 9.3 SECUENCIADORES DE ESTADO Según se mencionó en la Sección ??, un contador sincrónico es simplemente un secuenciador con una secuencia de estados numéricamente ascendente. Por tanto, el diseño de un secuenciador general es similar al diseño de un contador sincrónico. Supongamos que se debe generar la secuencia mostrada en el diagrama de estado de la Figura 9.3. Se requieren tres flip flops para representar los tres bits del estado posible más alto: en este ejemplo, el estado 7. El siguiente paso es la construcción de la tabla de transición, la cual se muestra en la Tabla ??. Como antes, los valores de J K son los requeridos para lograr que cada flip flop efectúe 122 CAPÍTULO 9. SECUENCIADORES DE ESTADO Y CONTROLADORES Figura 9.3: Diagrama de estado de un secuenciador de estado. la transición apropiada. En la Figura 9.4 se muestra la derivación de las ecuaciones. El diagrama lógico para implementar este contador se muestra en la Figura 9.5. 9.3.1. Estados no utilizados Para el secuenciador definido por el diagrama de estado de la Figura 9.3, los estados 3,5 y 6 no se muestran. Puesto que estos estados no son parte de la secuencia, las expresiones para J y K se pueden hacer más simples omitiéndolos de la Tabla de transición (su presencia resultarı́a en condiciones “no importa” en los mapas K). Pero si el secuenciador se energiza en uno de estos estados no utilizados, ?´qué sucederı́a en los ciclos de reloj sucesivos? Generalmente, después de que se completa el diseño, se determina la secuencia a partir de cada estado no utilizado y se agrega a la Tabla de transición y al diagrama de estado. La secuencia a partir de un estado no utilizado se determina asumiendo que el estado presente de las salidas es uno de los no utilizados. Calculando las entradas J y K a cada flip flop a partir de las ecuaciones, se puede determinar el máximo estado para flip flop. Las Figuras 9.6, 9.7 y 9.8 ilustran este proceso para los estados 3, 5 y 6 respectivamente. Como puede verse, el estado 3 pasa al estado 4, el cual pertenece a la secuencia normal. El estado 6 pasa al estado 0, el cual también pertenece a la secuencia normal. Estas transiciones deben agregarse al diagrama de estado original, según se muestra en la Figura 9.9. Si un estado no utilizado nunca entra al ciclo normal o si algunos estados no utilizados deben entrar a un estado especı́fico del ciclo, deben incluirse esas transiciones de estado en la Tabla de transiciones del diseño original y en las expresiones para las entradas J K. 9.3. SECUENCIADORES DE ESTADO @ Qb Qa Qc @ 00 @ 0 01 10 ' 0 0 0 1 11 1 X X 4 5 1 X 3 $ 123 @ Qb Qa Qc @ 00 @ 0 2 X 0 X X 7 6 & % 01 1 X 1 0 4 0 01 0 1 11 1 1 1 10 $ X 3 X X X 6 % X 0 1 X 1 1 X 0 X 3 4 5 & X 6 % 1 X 1 X 3 2 1 X 4 5 & 10 $ 7 @ Qb Qa 01 Qc @ 00 @' 0 X 6 7 6 % X 1 1 X % 10 $ X 3 X 2 1 X 4 5 & Ja = Qb 11 1 X 0 2 X 11 Kb = 1 @ Qb Qa 01 11 10 Qc @ 00 @' $ 1 1 X 1 Jb = Qc + Qa 0 X 2 X @ Qb Qa 01 Qc @ 00 @' 0 X 2 4 5 7 & 0 X 3 Kc = Qb ' 0 10 $ 5 7 & Jc = Qb @ Qb Qa Qc @ 00 @ 11 ' 7 X 6 % Ka = 1 Figura 9.4: Reducciones con mapas K y ecuaciones J K. Figura 9.5: Diagrama lógico del secuenciador de la Figura 9.4. Qc Qb Qa Estado actual 0 1 1 Entradas J Jc = Qb = 1 Jb = Qa + Qc = 1 Ja = Qb = 1 Entradas K Kc = Qb = 1 Kb = 1 Ka = 1 Q Qc cambia Qb cambia Qa se borra Próximo Estado 1 0 0 Figura 9.6: Determinación de siguiente estado a partir del estado 3. 124 Qc Qb Qa CAPÍTULO 9. SECUENCIADORES DE ESTADO Y CONTROLADORES Estado actual 1 0 1 Entradas J Jc = Qb = 0 Jb = Qa + Qc = 1 Ja = Qb = 1 Entradas K Kc = Qb = 0 Kb = 1 Ka = 1 Q Qc no cambia Qb cambia Qa cambia Próximo Estado 1 1 0 Figura 9.7: Determinación de siguiente estado a partir del estado 5. Qc Qb Qa Estado actual 1 1 0 Entradas J Jc = Qb = 1 Jb = Qa + Qc = 1 Ja = Qb = 0 Entradas K Kc = Qb = 1 Kb = 1 Ka = 1 Q Qc cambia Qb cambia Qa cambia Próximo Estado 0 0 0 Figura 9.8: Determinación de siguiente estado a partir del estado 6. Figura 9.9: Diagrama de estado final. 9.3. SECUENCIADORES DE ESTADO 125 Figura 9.10: Diagrama de estado. 9.3.2. Secuenciadores con control externo En ocasiones la secuencia de estados generada debe ser alterada por entradas externas. En estas aplicaciones, el estado que sigue depende no solamente del estado actual sino también de las entradas externas. Por tanto, las ecuaciones para las entradas J K deben ser función no solamente del estado actual sino de las entradas externas. Consideremos un sistema con dos ciclos. Un ciclo va de 0 a 2 y el segundo ciclo va de 3 a 5. La entrada externa Y se utiliza para determinar cuál ciclo debe ejecutarse. Si Y es 0, debe ejecutarse el primer ciclo y si Y es 1, debe ejecutarse el segundo ciclo. El primer ciclo entra y sale solamente por el estado 0; el segundo ciclo entra y sale por el estado 3. Este comportamiento se muestra en el diagrama de estado de la Figura 9.10 En la Tabla ?? se muestra la Tabla de transición. La determinación de las expresiones reducidas se muestra en la Figura 9.11. El diseño del diagrama lógico y la determinación de las transiciones no utilizadas se dejan como ejercicio al lector. 126 CAPÍTULO 9. SECUENCIADORES DE ESTADO Y CONTROLADORES @ Qb Qa 00 Y Q@ c @ 00 01 0 0 0 01 1 01 X 0 X 15 0 9 11 1 0 10 11 10 X 8 01 00 0 1 0 01 1 0 11 5 0 X 13 1 01 X X 1 X 11 X X 10 % 01 11 1 01 1 4 11 10 X 1 10 1 X X X X X X X X 00 X 15 X X 14 1 X 11 01 10 01 % 0 10 11 5 X 9 % X 6 X 15 1 X 8 X 2 7 0 X 10 1 3 0 X 12 13 ' 8 9 11 10 & & % % 11 1 X 0 1 & 4 X Ja = Qb + Qa X 6 @ 14 1 X X 8 9 & 1 2 7 13 @ Qb Qa 00 Y Q@ c 6 15 1 3 5 12 2 7 13 0 X 3 5 12 10 X 1 0 10 Kb = 1 @' ' $ $ 00 11 X Jb = Y Qc + Qa @ Qb Qa 00 Y Q@ c X 10 % $ 1 4 14 8 9 11 & X 01 X 0 6 15 X 14 @' 00 X X 1 @ Qb Qa 00 Y Q@ c 2 7 1 12 10 X 1 4 10 $ 3 X 15 Kc = Qa 11 ' @ X 6 9 11 & Jc = Y Qb Qa @ Qb Qa 00 Y Q@ c X 1 13 X 2 7 0 12 X 1 5 10 $ 3 0 14 11 X 1 4 X 01 ' X 0 X X 13 8 00 7 6 X 10 0 2 X 5 12 @ Qb Qa 00 Y Q@ c @ 10 0 3 X 4 11 11 X $ 14 X 11 Ka = Qc Figura 9.11: Reducciones por mapas K y ecuaciones JK. X 10 Capı́tulo 10 Registros Conceptos básicos Estructura de un registro Registros de desplazamiento Entradas y salidas de un registro Entradas o salidas serie o paralelo Interfaces de registros con otros sistemas Registros disponibles comercialmente Saber Hacer Reconocer la estructura de un registro Reconocer la necesidad de utilización de un registro 127 128 CAPÍTULO 10. REGISTROS Figura 10.1: Registro de cuatro bits que usa flip flops D 10.1 DEFINICIÓN En general, un registro es un circuito secuencial que puede ser colocado en un estado especial y retener ese estado hasta que sea cambiado externamente. Este estado puede ser un valor binario de varios bits en un computador, una dirección en un bus o aún, un bit único representado por un LED que debe prender o apagar. 10.2 DISEÑO DE LOS REGISTROS El latch S R discutido en el capı́tulo 6 es realmente un registro simple de un bit. Con la entrada S, la salida del latch se puede colocar en 1. Con la entrada R, la salida del latch se puede colocar en 0. En ambos casos, la salida permanece con el mismo valor hasta que sea cambiado externamente. Generalmente se desea tener una sola lı́nea de datos en lugar de lı́neas separadas, como en el latch S R. Por ejemplo, podemos usar el flip flop D como un registro de 1 bit. Con el flip flop cuádruple D 7474 utilizado en el laboratorio, la salida cambia de estado en el vértice delantero del reloj de entrada. Puesto que la entrada de reloj determina cuando cambia de estado el flip flop, puede considerarse una señal de cargue. En el flanco delantero de esta señal de cargue, el dato que está en la entrada se almacena en el flip flop. 10.2.1. Registros de bits múltiples Los registros de un bit obviamente tienen aplicación limitada. ¿Cómo puede construirse un registro de varios bits? En la Figura 10.1 se muestra un registro de 4 bits hecho de cuatro flip flops D. Cada flip flop almacena 1 bit. La entrada de reloj a cada flip flop proviene de una señal de cargue común. En el flanco delantero de la señal de cargue, cada flip flop almacena el valor que está en la entrada D. Se pueden construir registros con más bits, agregando un flip flop por cada bit adicional. 10.2. DISEÑO DE LOS REGISTROS 129 Figura 10.2: Registro de desplazamiento de cuatro bits con entrada serial y con salida paralela 10.2.2. Registros de Desplazamiento Los datos son cargados paralelamente en los registros multi bits discutidos anteriormente, según puede verse en la Figura 10.1. Pero en muchas aplicaciones, los datos no están disponibles en un formato paralelo; por ejemplo, considere el problema de recibir serialmente un valor de 4 bits. En esta aplicación, los datos vienen en una sola lı́nea, 1 bit cada vez. Suponga que los datos son enviados de tal forma que en primer lugar aparece el bit menos significativo y que una señal de reloj es activada cuando cada bit está disponible. El circuito receptor necesita ejecutar una conversión serial a paralelo, almacenando cada bit a medida que se recibe y luego de alguna manera, presentar el valor resultante de 4 bits. En la Figura 10.2 se muestra un circuito que ejecutará la conversión serial a paralelo. Como puede verse, la entrada D al primer flip flop es la lı́nea serial de los datos de entrada. La entrada de datos a cada flip flop adicional es la salida del flip flop anterior. La señal “bit disponible” va a la entrada del reloj de cada flip flop. Cuando esta señal se activa, cada flip flop cargará el dato que está en su entrada D. Debido a las conexiones, el primer flip flop almacenará el valor de la entrada serial y cada flip flop adicional almacenará la salida del flip flop precedente. Por tanto, el valor de 4 bits representado por los 4 flip flops, se desplaza una posición a la derecha y la posición de la izquierda se llena con el bit serial que llega. Si esta operación se repite cuatro veces, el primer bit recibido estará disponible en Qa , el segundo en Qb , etc. El circuito mostrado en la Figura 10.2 es realmente un registro de desplazamiento de 4 bits. En un registro de desplazamiento normal, a la entrada “bit disponible” tı́picamente se le llama entrada de reloj. El registro de desplazamiento mostrado en la Figura 10.2 tiene una entrada en serie y una salida en paralelo, puesto que los datos son cargados serialmente y quedan disponibles en paralelo en las salidas. Un registro de desplazamiento con entrada en serie y salida en paralelo, puede ejecutar la conversión “serie a paralelo” necesaria para recibir la información serial pero ?´Cómo se ejecuta la conversión “paralelo a serial” necesaria para enviar los datos en forma serial? En esta aplicación, los datos son almacenados en el registro en paralelo y desplazados hacia afuera a razón de un bit cada vez. Esto se puede efectuar con un registro de desplazamiento con entrada en paralelo y salida en serie. 130 CAPÍTULO 10. REGISTROS Figura 10.3: Registro de desplazamiento de cuatro bits con entrada paralela y salida serial En general, la operación de desplazamiento se ejecuta conectando la entrada de cada flip flop a la salida del flip flop anterior, según se muestra en la Figura 10.2. Pero con un registro de desplazamiento con entrada en paralelo y salida en serie, debemos estar en capacidad de colocar un valor externo en la entrada D de cada flip flop anterior para ejecutar el desplazamiento o una entrada de datos externa para cargar el registro en paralelo. Seleccionar una de dos fuentes se puede llevar a cabo fácilmente usando un mux de 2 a 1, como se mostró en el capı́tulo 3. Debido a este requisito de selección, se requiere una segunda entrada de control, además del reloj, con el fin de determinar si debe desplazarse o cargarse. En la Figura 10.3 se muestra un registro de desplazamiento con entrada paralela y salida serial. La selección entre el desplazamiento y el cargue en paralelo se ejecuta por medio de la lı́nea “desplazamiento/cargue”. Los anteriores términos indican que se ejecuta un desplazamiento si la lı́nea está baja y se efectúa un cargue en paralelo, si la lı́nea está alta. Utilizando 4 flip flops 7474 como los utilizados en el laboratorio, la operación de cargue o de desplazamiento tendrá lugar en el flanco de subida de la señal del reloj. La salida serial del registro de desplazamiento está sobre Qa. Puesto que algo debe desplazarse hacia el flip flop en una operación de desplazamiento, un registro de desplazamiento con entrada paralela generalmente tendrá una entrada serial, según se muestra en la figura 10.3. Para usar el registro de desplazamiento que transmita serialmente una palabra de 4 bits, la lı́nea desplazamiento/cargue se coloca en alto y se carga el valor de 4 bits en el registro en el primer ciclo del reloj. En este momento, el bit menos significativo estará disponible en la salida; antes del siguiente ciclo del reloj, la lı́nea desplazamiento/cargue se regresa a “bajo” de modo que en los ciclos sucesivos del reloj, el valor de 4 bits será desplazado a la derecha y el siguiente bit quedará disponible a la salida. 10.2.3. Latches Transparentes Con los registros discutidos hasta ahora, los valores son almacenados con base en un reloj o señal de cargue. El valor de salida cambia solamente cuando se carga un valor nuevo en el flanco del reloj. Otro tipo de registro, denominado comúnmente “latch transparente”, opera de una manera ligeramente diferente. En lugar de una señal de reloj o de cargue, el latch transparente tiene una compuerta o entrada de habilitación. Cuando se habilita, 10.3. INTERFACES DE REGISTROS CON OTROS MÓDULOS 131 las salidas del latch toman el valor de la entrada. Excepto por el retardo de propagación del latch, éste es transparente. Cuando no está habilitado, las salidas permanecen en el mismo estado como estaban en el instante en que desapareció la señal de habilitación. Por ejemplo, suponga que existe un latch transparente con una habilitación activa alta. Mientras esta habilitación está alta, las salidas toman el valor de las entradas; cuando la lı́nea de habilitación está baja, las salidas permanecen en el estado existente cuando la lı́nea estaba baja. Nótese la similitud con el latch S R controlado por la compuerta, discutido anteriormente. Los latches transparentes tienen varias aplicaciones. Por ejemplo, para reducir el número de pines de un integrado, algunos microprocesadores multiplexan las lı́neas de datos con las lı́neas de dirección, es decir, los mismos pines se usan tanto para el bus de direcciones como para el bus de datos. Durante la mitad de un ciclo del reloj maestro, los pines representan la dirección a la cual se está accediendo. Durante la otra mitad del ciclo, esos mismos pines representan las lı́neas de datos. Con este tipo de procesador, puede usarse un latch transparente para mantener el valor original de las lı́neas de dirección durante la segunda mitad del ciclo cuando esas mismas lı́neas se vuelven lı́neas de datos. 10.3 INTERFACES DE REGISTROS CON OTROS MÓDULOS Hemos considerado el diseño y la operación de los registros, pero ?´cómo incorporar esos registros en un circuito digital? Con el fin de ilustrar las aplicaciones y las técnicas de realización de interfaces, se conectará un registro a un sistema microprocesador. Supongamos que este microprocesador tiene un bus de direcciones de 16 bits para el direccionamiento de la memoria y de los periféricos. En el capı́tulo 5 se ilustró un esquema sencillo de decodificación de direcciones usando un decodificador para habilitar uno de 4 chips RAM. Basados en la dirección, el decodificador acciona la lı́nea de habilitación del chip RAM apropiado. Asumiremos un esquema similar de decodificación de direcciones para interconectar el registro al microprocesador. Cuando el microprocesador se dirija al registro, la lı́nea de habilitación de éste tomará el valor bajo. A esto lo llamaremos habilita. Se usará un bus de 8 bits para transmitir datos desde el procesador y hacia él. La lı́nea lea tomará el valor bajo cuando el microprocesador hace la lectura del dispositivo seleccionado y la lı́nea escriba tomará el valor bajo cuando el microprocesador escriba el dispositivo seleccionado. Para sincronizar los eventos existe una señal del reloj maestro, MCLK. La dirección (y por tanto, la señal habilita) y las señales lea y escriba se vuelven válidas durante la primera mitad del ciclo MCLK. El microprocesador lee el bus de datos en el flanco descendente de MCLK. Los datos escritos procedentes del microprocesador son válidos en el flanco descendente de MCLK. Por tanto, los periféricos deben almacenar los datos procedentes del bus de datos en el flanco descendente del MCLK. La Figura 10.4 incluye la información sobre tiempos. 132 CAPÍTULO 10. REGISTROS Figura 10.4: Temporización del microprocesador Figura 10.5: Temporización del cargue del registro. 10.3.1. Interfaz de un Registro de Escritura Solamente Un registro externo tiene muchos usos en un sistema con microprocesador. Por ejemplo, podrá usarse la salida de un registro de 8 bits para manejar 8 LED indicadores. El microprocesador podrá iluminar cualquier combinación en los LED almacenando diferentes valores en el registro; aquı́ el procesador únicamente escribe en el registro. ?´Cómo se interconectan el microprocesador y el registro en este tipo de aplicación? La primera preocupación es cuándo cargar el registro con los datos del bus de datos. Obviamente que esto debe hacerse solamente cuando el microprocesador está escribiendo en el registro. Cuando esto ocurre, la lı́nea escriba baja y la lı́nea habilita para el registro también baja, puesto que la dirección que está en el bus es la del registro. Si estas dos lı́neas están bajas, el registro debe cargarse con los datos del bus de datos en el flanco descendente de MCLK. Los registros diseñados en la sección ?? cargaban los datos en el flanco ascendente del reloj. Nos referimos a esta señal como “Cargue”. Los requisitos de interconexión se pueden resumir como sigue: Si escriba es bajo y habilita es bajo, entonces en el flanco descendente de MCLK, “Cargue” debe volverse alta para cargar el registro. Esta secuencia podrá ocurrir como se muestra en la Figura 10.5. Ahora que están definidos los requisitos de tiempo de la interfaz, ?´cómo puede generarse la señal “cargue”? En la Figura 10.5 vemos que si escriba está baja, habilita está baja y MCLK está alta, entonces la lı́nea “cargue” debe bajar. Esto es simplemente la función NAND, según se muestra en la Figura ??. Inspeccionando el circuito, vemos que “cargue” baja sólo cuando escriba y habilita están bajas y MCLK está alto. Tan pronto como MCLK baja, “cargue” sube para escribir en el registro según se desea. 10.3. INTERFACES DE REGISTROS CON OTROS MÓDULOS 133 Figura 10.6: Generación de la señal de cargue 10.3.2. Interfaz de un registro de lectura solamente Otros usos de los registros incluyen aplicaciones en las que un evento externo almacena un valor en el registro para ser leı́do más tarde por el microprocesador. Por ejemplo, consideremos un circuito de codificación del teclado para un teclado numérico sencillo. Este circuito convierte el cierre de una tecla en un valor binario que representa la tecla oprimida, almacena este valor en un registro y luego le señala al microprocesador que ya está disponible un nuevo valor. El microprocesador entonces lee el registro para obtener el valor de la tecla pulsada. Los requisitos de interconexión son muy diferentes de los vistos para escribir en un registro en la sección ??. ?´Cómo podemos generar una señal para leer el registro en el momento apropiado? Recordemos que las salidas del registro son simplemente las salidas de los flip flops. Estas salidas están siempre encendidas. Si un flip flop está almacenando un 1, la salida será 1. ?´Cómo podemos leer selectivamente este registro si la salida siempre está encendida? Para responder a esta pregunta, miremos el funcionamiento del bus de datos. Cuando el microprocesador está escribiendo, sus salidas están manejando el bus de datos: ningún otro dispositivo está intentando colocar un valor en el bus de datos. De forma similar, cuando el microprocesador está leyendo, solamente las salidas del dispositivo seleccionado están manejando el bus de datos. El único momento en que las salidas de un dispositivo deben conectarse al bus de datos debe ser cuando el microprocesador está tomando la lectura de ese dispositivo. En cualquier otro momento, las salidas del dispositivo deben estar efectivamente desconectadas del bus de datos. La pregunta obvia es ?´cómo hacer para desconectar las salidas del bus de datos? Recordemos del capı́tulo ?? la existencia de compuertas con salidas de tres estados. Estas salidas pueden asumir los estados normales 0 y 1 pero adicionalmente, pueden asumir un tercer estado que parece un circuito abierto como si nada estuviese allı́. Cuando la salida está en el tercer estado, efectivamente se desconecta del circuito. Para conectar el tercer estado, se usa una lı́nea de habilitación. Cuando se habilita, la salida asume los valores normales uno o cero. Cuando no se habilita, la salida está en el tercer estado o desconectada. Se puede conseguir la habilitación activa alta como la activa baja. En la Figura 10.7 se muestra un registro de 4 bits con cuatro compuertas de tercer estado en las salidas. Estas compuertas simplemente pasan el valor de la entrada a la 134 CAPÍTULO 10. REGISTROS Figura 10.7: Registro de cuatro bits con salidas de tercer estado Figura 10.8: Temporización de la lectura del registro salida con la capacidad de habilitar o deshabilitar la salida. Estas compuertas a menudo se les denominan “buffers” de tercer estado. Estos “Buffers” están disponibles en chips TTL. Por ejemplo, el 74367 tiene 6 de estos buffers en un chip. El 74368 contiene seis inversores de tercer estado. El 74LS244 tiene 8 de estos buffers en un solo chip y es especialmente útil en aplicaciones con microprocesadores de 8 bits. Usando buffers de tercer estado, podemos conectar la salida de un registro al bus de datos, operación que debe efectuarse sólo cuando el microprocesador está haciendo la lectura de ese registro. Cuando esto ocurre, la lı́nea Lea baja ası́ como también la lı́nea habilita de ese registro puesto que la dirección que está en el bus corresponde a ese registro. La salida del registro debe conectarse al bus de datos antes del flanco descendente de MCLK que es cuando el procesador realiza la lectura del valor del bus. Para conectar el registro al bus, simplemente habilitamos las salidas de los buffers de tercer estado. Asumiremos que la lı́nea de habilitación es activa baja como en la Figura 10.7. La secuencia de eventos podrá ocurrir según se muestra en la Figura 10.8. Como puede verse, la habilitación de salida baja sólo cuando lea y habilita están bajas y MCLK está alto. Durante este tiempo, la salida del registro se conectará al bus de datos y por tanto serán válidos en el flanco descendente de MCLK. La generación de la señal habilita es simplemente una operación NAND según se muestra en la Figura 10.9. 10.4. REGISTROS DISPONIBLES COMERCIALMENTE 135 Figura 10.9: Generación de la señal para habilitar la salida 10.3.3. Conectando un Registro de Lectura/Escritura Algunas aplicaciones utilizan un registro como una celda de memoria rápida; un ejemplo lo constituyen los registros de propósitos generales del computador. En estas aplicaciones se lee el registro e igualmente se escribe en él. La misma dirección se usa tanto para leer como para escribir, determinándose entonces mediante Lea o escriba cuál es la operación que se va a efectuar. Simplemente combinando los circuitos definidos en las secciones ?? y ?? se puede obtener el circuito para esta aplicación. 10.4 REGISTROS DISPONIBLES COMERCIALMENTE Se dispone de muchas variaciones de registros en los chips TTL. El 74175 es un registro de 4 bits que utiliza cuatro flip flops D como los de la Figura 10.1 . El 74174 es similar al 74175 pero tiene seis bits mientras que el 74273 tiene 8 bits. Además de las lı́neas de datos y una entrada de reloj, cada uno de estos registros tiene una entrada de borrado para iniciar el registro en cero. A fin de reducir los requisitos de interconexión, el registro de 8 bits 74LS377 tiene una entrada de habilitación ası́ como una de reloj para almacenar los datos. A menos que la lı́nea de habilitación sea baja, la entrada del reloj se ignora. El registro de 8 bits 74LS364 tiene salidas de tercer estado, que eliminan la necesidad de tener un chip con buffer separado. El 74LS363 es similar al 74LS364, sólo que tiene un latch transparente. En lugar de tener una entrada de reloj tiene una entrada de habilitación. Los registros de desplazamiento están disponibles en una gran variedad. El 7495 es un registro de desplazamiento de 4 bits con entrada paralela y salida paralela. Este registro se puede cargar paralelamente o se puede desplazar serialmente del mismo modo que el registro de desplazamiento mostrado en la Figura 10.3. 136 CAPÍTULO 10. REGISTROS Capı́tulo 11 Aplicaciones Secuenciales en VHDL Conceptos básicos Flip-Flops Contadores Secuenciadores Máquinas de Estado Registros Saber Hacer Describir en VHDL un sistema secuencial Simular el comportamiento del circuito 137 138 CAPÍTULO 11. APLICACIONES SECUENCIALES EN VHDL 11.1 FLIP-FLOPS 11.2 Los procesos de VHDL Los dispositivos de lógica secuencial necesitan todos para su implementación del mecanismo del proceso (“process”) de VHDL. La forma general de un proceso en VHDL es la siguiente: PROCESS (lista de sensibilidad) Declaraciones de variables BEGIN Proposiciones secuenciales END PROCESS Un proceso se ejecuta cuando cualquiera de las señales incluidas en la lista de sensibilidad que va en el encabezado cambia. Dentro del cuerpo del proceso se puede manejar cual de las señales fue la que cambió por medio del atributo EVENT que se le puede agregar a una señal; por ejemplo, clock’ EVENT, es una condición que se vuelve verdadera cuando la señal clock cambia de valor. 11.3 Los Flip-Flops En el ejemplo que sigue incluimos varias implementaciones de flip-flops tipo D, para los cuales se ha seleccionado que el disparo se haga en el lado delantero del reloj. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 library ieee ; use ieee . std_logic_1164 . all ; entity DFFs is port ( D , Clock , Reset , Enable Q1 , Q2 , Q3 , Q4 end DFFs ; : in std_logic ; : out std_logic ) ; architecture behavior of DFFs is begin -- Flip flop D process begin wait until ( Clock ’ event and Clock = ’1 ’) ; Q1 <= D ; end process ; 11.4. REGISTRO 4 BITS 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 -- Flip - Flop D process begin wait until if reset = then Q2 <= else Q2 <= end if ; end process ; 139 con reset sincrónico ( Clock ’ event and Clock = ’1 ’) ; ’1 ’ ’0 ’; D; -- Flip - Flop D con reset asincrónico process ( Reset , Clock ) begin if reset = ’1 ’ then Q3 <= ’0 ’; elsif ( clock ’ event and clock = ’1 ’) then Q3 <= D ; end if ; end process ; -- Flip - Flop D con reset y habilitación asincrónicos process ( Reset , Clock ) begin if reset = ’1 ’ then Q4 <= ’0 ’; elsif ( clock ’ EVENT AND clock = ’1 ’) then if Enable = ’1 ’ then Q4 <= D ; end if ; end if ; end process ; end behavior ; Listado 11.1: Flip-Flops. 11.4 Registro 4 bits Como puede observase en la tabla que describe el comportamiento del circuito, si CLR = 0, las salidas Q adoptan el valor de 0; pero si CLR = 1, toman el valor de las entradas D0 , D1 , D2 y D3 . El código del programa se observa en el siguiente listado. 140 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 CAPÍTULO 11. APLICACIONES SECUENCIALES EN VHDL library ieee ; use ieee . std_logic_1164 . all ; entity reg4 is port ( D : in std_logic_vector (3 downto 0) ; CLR , CLK : in std_logic ; Q , Qn : inout std_logic_vector (3 downto 0) ) ; end reg4 ; architecture a_reg4 of reg4 is begin process ( CLK , CLR ) begin if ( CLK ’ event and CLK = ’1 ’) then if ( CLR = ’1 ’) then Q <= D ; Qn <= not Q ; else Q <= " 0000 " ; Qn <= " 1111 " ; end if ; end if ; end process ; end a_reg4 ; Listado 11.2: Registro de 4 bits. Las variables sensitivas que determinan el comportamiento del circuito se encuentran dentro del proceso (CLR y CLK). 11.5 Contador binario de 4 bits La señal de control Up/Down permite definir si el conteo se realiza en sentido ascendente o descendente. En este caso, un cero aplicado a esta señal determina una cuenta ascendente: del 0 al 15. De esta forma, el funcionamiento del circuito queda determinado por dos señales: el pulso de reloj (clk) y la señal Up/Down, como se muestra en el siguiente programa. 1 2 3 library ieee ; use ieee . std_logic_1164 . all ; use ieee . std_logic_signed . all ; 11.6. MÁQUINA DE ESTADOS FINITA 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 141 entity contador is port ( clk : in std_logic ; up : in std_logic ; Q : inout std_logic_vector (3 downto 0) ) ; end contador ; architecture a_contador of contador is begin process ( up , clk ) begin if ( clk ’ event and clk = ’1 ’) then if ( up = ’0 ’) then Q <= Q + 1 ; else Q <= Q - 1; end if ; end if ; end process ; end a_contador ; Listado 11.3: Contador binario de 4 bits. 11.6 Máquina de estados finita En la figura se puede observar que el circuito pasa al estado q1 con el primer 1 de entrada (x) y al estado q2 con el segundo. Las salidas (z) asociadas con estas dos entradas son 0, según se señala. La tercera entrada consecutiva de 1 genera un 1 en la salida y hace que el circuito pase al estado q3 . Una vez que se encuentre en q3 , el circuito permanecerá en este estado, emitiendo salidas O. Las ideas nuevas de VHDL, provienen de usar estructuras case - when y tipo de datos enumerados, que en este caso contiene los cinco estados (q0 , q1 , q2 , q3 y q4 ) que componen el diagrama. El listado correspondiente al programa se encuentra a continuación. 1 2 3 4 5 6 7 library ieee ; use ieee . std_logic_1164 . all ; entity diag is port ( clk , x : in std_logic ; z : out std_logic ) ; end diag ; 142 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 CAPÍTULO 11. APLICACIONES SECUENCIALES EN VHDL architecture a_diag of diag is type estados is ( q0 , q1 , q2 , q3 , q4 ) ; signal estado_presente , estado_futuro : estados ; begin proceso1 : process ( estado_presente , x ) begin case estado_presente is when q0 = > z <= ’0 ’; if x = ’0 ’ then estado_futuro <= q4 ; else estado_futuro <= q1 ; end if ; when q1 = > z <= ’0 ’; if x = ’0 ’ then estado_futuro <= q4 ; else estado_futuro <= q2 ; end if ; when q2 = > if x = ’0 ’ then estado_futuro <= q4 ; z <= ’0 ’; else estado_futuro <= q3 ; z <= ’1 ’; end if ; when q3 = > z <= ’0 ’; if x = ’0 ’ then estado_futuro <= q3 ; else estado_futuro <= q3 ; end if ; when q4 = > z <= ’0 ’; if x = ’0 ’ then estado_futuro <= q4 ; else estado_futuro <= q1 ; end if ; end case ; end process proceso1 ; proceso2 : process ( clk ) begin if ( clk ’ event and clk = ’1 ’) then estado_presente <= estado_futuro ; end if ; 11.7. LAS LUCES DEL FORD 55 56 57 143 end process proceso2 ; end a_diag ; Listado 11.4: Máquina de estados finita. 11.7 Las luces del Ford Este ejemplo es tomado del libro de Wakerly. Se refiere al lector a dicho libro para más detalles del problema. La máquina secuencial a desarrollar tiene 3 variables de entrada, denominadas left, right y haz, que corresponden a los controles de las señales de las luces direccionales. La máquina debe controlar seis luces de salida, tres a cada lado del vehı́culo en la parte trasera, de tal modo que cuando se seleccione la señal left, por ejemplo, las luces de salida deben mostrar primero 001000, luego 011000, luego 111000 y finalmente 000000, y reiniciar la secuencia. El diagrama de estados de la máquina pedida se muestra en la siguiente figura: El programa correspondiente en VHDL se incluye a continuación: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Library IEEE ; use IEEE . std_logic_1164 . all ; entity vtbird is port ( CLOCK , RESET , LEFT , RIGHT , HAZ : in STD_LOGIC ; LIGHTS : buffer STD_LOGIC_VECTOR (1 to 6) ) ; end ; architecture vtbird_arch of vtbird constant IDLE : STD_LOGIC_VECTOR (1 constant L3 : STD_LOGIC_VECTOR (1 constant L2 : STD_LOGIC_VECTOR (1 constant L1 : STD_LOGIC_VECTOR (1 constant R1 : STD_LOGIC_VECTOR (1 constant R2 : STD_LOGIC_VECTOR (1 constant R3 : STD_LOGIC_VECTOR (1 constant LR3 : STD_LOGIC_VECTOR (1 begin process ( CLOCK ) begin if CLOCK ’ event and CLOCK = if RESET = ’1 ’ then LIGHTS <= IDLE ; else case LIGHTS is is to to to to to to to to 6) 6) 6) 6) 6) 6) 6) 6) := := := := := := := := ’1 ’ then " 000000 " ; " 111000 " ; " 110000 " ; " 100000 " ; " 000001 " ; " 000011 " ; " 000111 " ; " 111111 " ; 144 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 CAPÍTULO 11. APLICACIONES SECUENCIALES EN VHDL when IDLE = > if HAZ = ’1 ’ or ( LEFT = ’1 ’ and RIGHT = ’1 ’) then LIGHTS <= LR3 ; elsif LEFT = ’1 ’ then LIGHTS <= L1 ; elsif RIGHT = ’1 ’ then LIGHTS <= R1 ; end if ; when L1 = > if HAZ = ’1 ’ then LIGHTS <= LR3 ; else LIGHTS <= L2 ; end if ; when L2 = > if HAZ = ’1 ’ then LIGHTS <= LR3 ; else LIGHTS <= L3 ; end if ; when L3 = > LIGHTS <= IDLE ; when R1 = > if HAZ = ’1 ’ then LIGHTS <= LR3 ; else LIGHTS <= R2 ; end if ; when R2 = > if HAZ = ’1 ’ then LIGHTS <= LR3 ; else LIGHTS <= R3 ; end if ; when R3 = > LIGHTS <= IDLE ; when LR3 = > LIGHTS <= IDLE ; when others = > null ; end case ; end if ; end if ; end process ; end vtbird_arch ; Listado 11.5: Las luces del Ford. 11.8. SEMÁFORO 11.8 145 Semáforo Este ejemplo es tomado del libro de Floyd en el numeral 6.11, a donde puede referirse el lector para obtener más detalles sobre el problema. A continuación se muestra el programa VHDL de ésta aplicación: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 LIBRARY ieee ; USE ieee . std_logic_1164 . ALL ; ENTITY semaforos IS PORT ( sensor , reset , clk : IN std_logic ; semcamin , semcarr : OUT std_logic_vector (0 TO 2) ) ; END semaforos ; ARCHITECTURE descripcion OF semaforos IS TYPE estado IS ( PrimerEstado , SegundoEstado , TercerEstado , CuartoEstado ) ; CONSTANT verde : std_logic_vector (0 TO 2) := " 001 " ; CONSTANT amarillo : std_logic_vector (0 TO 2) := " 010 " ; CONSTANT rojo : std_logic_vector (0 TO 2) := " 100 " ; SIGNAL presente : estado := PrimerEstado ; SIGNAL rescont : boolean := false ; -- Pone a cero la cuenta SIGNAL fin_largo , fin_corto : boolean ; -- Indica fin de cuenta SIGNAL cuenta : integer RANGE 0 TO 63; BEGIN -- Definimos la máquina de estados : maquina : PROCESS ( clk , reset ) BEGIN IF reset = ’1 ’ THEN presente <= PrimerEstado ; ELSIF clk = ’1 ’ AND clk ’ event THEN CASE presente IS WHEN PrimerEstado = > IF sensor = ’1 ’ and fin_largo THEN presente <= SegundoEstado ; END IF ; WHEN SegundoEstado = > IF fin_corto THEN presente <= TercerEstado ; END IF ; WHEN TercerEstado = > IF sensor = ’0 ’ or not fin_largo THEN presente <= CuartoEstado ; END IF ; WHEN CuartoEstado = > IF fin_corto THEN presente <= PrimerEstado ; END IF ; 146 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 CAPÍTULO 11. APLICACIONES SECUENCIALES EN VHDL END CASE ; END IF ; END PROCESS maquina ; salida : PROCESS ( presente ) -- No depende de las entradas BEGIN CASE presente IS WHEN PrimerEstado = > semcarr <= verde ; semcamin <= rojo ; rescont <= true ; WHEN SegundoEstado = > semcarr <= amarillo ; semcamin <= rojo ; rescont <= true ; WHEN TercerEstado = > semcarr <= rojo ; semcamin <= verde ; rescont <= false ; WHEN CuartoEstado = > semcarr <= rojo ; semcamin <= amarillo ; rescont <= true ; END CASE ; END PROCESS salida ; -- El siguiente proceso define el contador : contador : PROCESS ( clk ) BEGIN IF clk = ’1 ’ THEN IF rescont THEN cuenta <=0; ELSE cuenta <= cuenta +1; END IF ; END IF ; END PROCESS contador ; -- Detección de los tiempos largos y cortos : fin_largo <= true WHEN cuenta =29 ELSE false ; fin_corto <= true WHEN cuenta =9 ELSE false ; END descripcion ; Listado 11.6: Semáforo.