Electrónica Digital · Tema 25

Comparadores

¿A es mayor, igual o menor que B? Es la pregunta detrás de cada if, de cada ordenamiento y de cada termostato. En hardware tiene una estructura clara: se decide desde el bit más alto, y el primer bit que difiere zanja la cuestión. Y hay una sorpresa: un comparador es, por dentro, el acarreo de una resta.

≈ 55 minutos Sin materiales: solo el navegador Incluye simulador y Python

01 · Punto de partida

¿Alcanza o se pasa?

Un termostato digital pregunta si la temperatura llegó a la consigna. Un cargador, si la tensión de la batería bajó del umbral. Una cerradura, si el código ingresado es igual al guardado. Son tres preguntas distintas con la misma forma: dos números de N bits entran, y sale uno de tres veredictos excluyentes: A > B, A = B o A < B. Siempre vale exactamente uno.

Una escena típica. Tenés una temperatura de 4 bits (0 a 15) y una consigna de 7. Con T = 5 el calefactor tiene que encenderse; con T = 9, apagarse; con T = 7 hay que decidir qué pasa justo en el borde. El comparador entrega las tres señales; vos decidís qué hacer con cada una.

En software es un if (a > b) … else if (a == b) … else …, o el operador de tres vías cmp(a, b) que devuelve menor, igual o mayor. En hardware, ese «menor, igual o mayor» son tres cables, y solo uno está en 1.

  • ¿Qué ecuaciones tiene el comparador de un bit?
  • ¿Por qué con N bits se decide desde el bit más alto?
  • ¿Cómo se arma la igualdad con XOR, y qué simplifica una constante?
  • ¿Qué relación hay entre comparar y restar, y cómo cambia con signo?
  • ¿Cómo se usa y se encadena el 74HC85?
  • ¿Para qué sirve un comparador además de comparar?

02 · De un bit a N bits

El bit alto manda

Un bit: tres veredictos excluyentes

Comparador de un bit.
A BG (A > B)E (A = B)L (A < B)
0 0010
0 1001
1 0100
1 1010

G vale 1 solo en 10, L solo en 01, y E en 00 y 11 (la coincidencia, el XNOR del Tema 10). Como E es «ni G ni L», se puede sacar con un NOR: el comparador de un bit cuesta 5 puertas (2 NOT, 2 AND y 1 NOR). Si ves dos salidas en 1 al mismo tiempo, el circuito está mal.

N bits: desde el más significativo

Para comparar números de varios bits se hace lo que hacés al ordenar palabras: se mira la primera letra; si difiere, ya está; si coincide, se pasa a la segunda. En binario la «primera letra» es el bit más significativo, porque pesa más que todos los demás juntos.

Cinco comparaciones de 4 bits. El bit que decide es el primero, de izquierda a derecha, que difiere.
ABBits que empatanDecideVeredicto
9 (1001)6 (0110)ningunobit 3 (1 contra 0)A > B
5 (0101)9 (1001)ningunobit 3 (0 contra 1)A < B
6 (0110)7 (0111)bits 3, 2 y 1bit 0 (0 contra 1)A < B
7 (0111)7 (0111)los cuatronadieA = B
8 (1000)7 (0111)ningunobit 3 (1 contra 0)A > B, aunque los tres bits bajos sean al revés

Escrito como ecuaciones, con Gi = Ai·~Bi, Li = ~Ai·Bi y Ei = Ai⊙Bi (el comparador de cada bit):

Comparador de 4 bits en forma de suma de productos.
SalidaEcuación
E (A = B)E3·E2·E1·E0
G (A > B)G3 + E3·G2 + E3·E2·G1 + E3·E2·E1·G0
L (A < B)L3 + E3·L2 + E3·E2·L1 + E3·E2·E1·L0
Cada término es un «si»
E3·E2·G1 se lee: «los bits 3 y 2 empatan y el bit 1 de A es mayor». Los E de los bits altos funcionan como una puerta que deja pasar la decisión de los bits de abajo solo si no hubo diferencia antes.
Como un else-if en silicio
La decisión corta en el primer bit que difiere: los bits siguientes quedan ignorados (en el simulador se ven grises). Es la evaluación en cortocircuito, hecha con compuertas.
Una sola salida en 1
E, G y L cubren todos los casos sin solaparse. Con 4 bits hay 256 pares: 120 con A > B, 16 con A = B y 120 con A < B (Paso 2).

03 · Igualdad

XOR, NOR y comparar con una constante

Muchas veces solo importa si dos valores son iguales, no cuál es mayor. Eso es mucho más barato:

  • Un XOR por bit vale 1 cuando ese bit difiere (Tema 10).
  • Una NOR de todos los XOR vale 1 cuando ninguno difiere, es decir, cuando los números son iguales.
Costo del comparador de igualdad con puertas de dos y cuatro entradas.
BitsXORNOR de 4 entradasAND de 2 entradasTotal
44105
882111
16164323
32328747

Con chips: un 74HC86 trae cuatro XOR y un 74HC4002 (si lo tenés a mano) dos NOR de cuatro entradas; en cuanto a comparadores de igualdad dedicados de 8 bits, existen en la serie 74 (por ejemplo, el 74HC688). Confirmá cada uno en su hoja de datos.

Comparar con una constante se simplifica

Si uno de los números es fijo, el XOR de cada bit desaparece: A xor 1 = ~A y A xor 0 = A. Para un código fijo 1010 (la cerradura del Ejercicio 2) alcanza con un AND de cuatro entradas con dos inversores: E = A3·~A2·A1·~A0. No hace falta ningún XOR.

04 · Magnitud, resta y signo

El comparador es el acarreo de una resta

Del Tema 24: A − B = A + ~B + 1, y el acarreo final vale 1 cuando A ≥ B. Más fino aún: si se suma A + ~B sin el +1, el acarreo final vale 1 exactamente cuando A > B, porque A + 15 − B alcanza 16 solo si A es mayor que B. Y con el +1 vale 1 cuando A ≥ B.

El comparador mirado como cadena de acarreo.
En el sumador (Tema 24)En el comparador
B se invierte (~B) y se suma a AHay que comparar A contra B bit a bit
Generate: Gi = Ai·~BiEl bit i de A «gana» (Ai = 1 y Bi = 0)
Propagate: Pi = Ai ⊕ ~BiEl bit i empata (Ei): deja pasar la decisión de abajo
Cout = G3 + P3·G2 + P3·P2·G1 + …G = G3 + E3·G2 + E3·E2·G1 + …

Son la misma ecuación. Un comparador es una cadena de acarreo a la que le quitaron el cálculo de las sumas: solo interesa el acarreo final, así que es más barato que un restador completo (Paso 4 lo verifica). Y todo lo que aprendiste sobre el acarreo anticipado sirve aquí: el comparador de 4 bits de la sección anterior es el acarreo anticipado.

Con signo y sin signo no dan lo mismo

Los patrones de bits no tienen signo propio: 1111 es 15 o −1 según cómo se lea (Tema 5). Y el orden cambia: sin signo 15 > 1, pero con signo −1 < 1. Hacen falta dos comparaciones distintas, aunque los bits sean los mismos.

El mismo par de bits, dos veredictos (4 bits).
ABSin signoCon signo
1111000115 > 1: A > B−1 < 1: A < B
100001118 > 7: A > B−8 < 7: A < B
001111013 < 13: A < B3 > −3: A > B
Truco: invertir el bit de signo
Para comparar con signo con un comparador sin signo, se invierte el bit más alto de A y de B antes de comparar. Eso equivale a sumar 2N−1 (8 con 4 bits) y traslada el rango −8..7 a 0..15 sin cambiar el orden. Con −1 contra 1: 1111 pasa a 0111 (7) y 0001 pasa a 1001 (9): 7 < 9 ✓.
O con los flags de la resta
Tras A − B (Tema 24): A < B sin signo es C = 0, A < B con signo es N ≠ V, y A = B es Z = 1.

05 · 74HC85

Un comparador de 4 bits con entradas de cascada

El 74HC85 compara dos palabras de 4 bits. Tiene las entradas de datos A3 a A0 y B3 a B0, tres entradas de cascada (IA>B, IA=B, IA<B) y tres salidas (QA>B, QA=B, QA<B). Los pines exactos conviene tomarlos de la hoja de datos del fabricante.

Función del 74HC85 con cascada válida (una sola entrada de cascada en 1).
Datos A y BEntradas de cascada > = <Salidas > = <
A > Bcualquiera1 0 0
A < Bcualquiera0 0 1
A = B1 0 01 0 0
A = B0 1 00 1 0
A = B0 0 10 0 1

Cuando los datos difieren, la cascada se ignora; cuando son iguales, el chip «hereda» lo que le dicen las entradas de cascada. Para usarlo solo (sin cascada) hay que poner IA=B = 1 y las otras dos en 0: así, con A = B, la salida «igual» se enciende.

Cascada para 8, 12 o 16 bits

  1. 1
    El chip de los 4 bits bajos va primero.

    Sus entradas de cascada son fijas: IA=B = 1, IA>B = 0, IA<B = 0. Compara A3..A0 contra B3..B0.

  2. 2
    Sus tres salidas pasan a las entradas de cascada del chip siguiente.

    El chip de los 4 bits altos compara A7..A4 con B7..B4. Si difieren, manda; si empatan, «hereda» el veredicto del chip bajo.

  3. 3
    Las salidas del último chip son el veredicto de 8 bits.

    Para 12 o 16 bits se agregan más chips en la misma cadena.

06 · Aplicaciones

Dónde aparece un comparador

Termostato con histéresis
Con un solo umbral, una temperatura que oscila alrededor de la consigna enciende y apaga el calefactor sin parar. La solución usa dos comparaciones: encender cuando T < bajo (L), apagar cuando T > alto (G), y entre ambos mantener el estado (un latch, Tema 11). Es la versión digital del disparador Schmitt (Paso 7).
Comparar y elegir: máximo y mínimo
Un comparador más un multiplexor (Tema 18) devuelve el mayor de dos números: G elige cuál de los dos pasa.
Compare-exchange y ordenamiento
Una celda que compara dos palabras y las intercambia si están al revés (un comparador y dos multiplexores por bit) es la pieza de las redes de ordenamiento. Cinco celdas ordenan cuatro valores (Paso 6), siempre en la misma secuencia, sin ramas ni datos que cambien el camino.
Verificar un rango
«Lo mínimo ≤ x ≤ lo máximo» son dos comparadores y un AND. Así se hacen las ventanas de tolerancia de una medición.
Convertidores y direcciones
Un conversor por aproximaciones sucesivas compara en cada paso contra una tensión de prueba. La decodificación de direcciones de una memoria compara los bits altos de la dirección contra un valor fijo (la igualdad con constante de la sección 03).

07 · Simulador

Laboratorio: el árbitro de 4 bits

El simulador muestra un comparador de 4 bits con el bit más alto a la izquierda. Con dos deslizadores elegís A y B (0 a 15). Cada columna es un bit: muestra los bits de A y B y las señales E (empate), G y L, y cambia de color según su papel. A la derecha están las tres salidas. Podés elegir tres modos: sin signo, con signo (se invierte el bit 3 de A y de B antes de comparar) y solo igualdad (XOR más NOR).

  • Columna verde: es el bit que decide (el primero, de izquierda a derecha, que difiere).
  • Columna turquesa: el bit empata y la decisión pasa al siguiente.
  • Columna gris: ya se decidió más arriba; ese bit no se mira.
  • Resultados: las tres salidas, el veredicto y una verificación contra el operador de comparación del lenguaje.
SIMULADOR 25

Árbitro de 4 bits

9 vs 6 → A>B

Comparador de cuatro bits Cuatro columnas, una por bit, desde el bit 3 a la izquierda. Cada columna muestra los bits de A y B y sus señales E, G y L. La columna que decide se dibuja en verde, las que empatan en turquesa y las ya decididas en gris. A la derecha están las salidas mayor, igual y menor. DE ARRIBA HACIA ABAJO: EL PRIMER BIT QUE DIFIERE DECIDE
A>B (G)● 1
A=B (E)○ 0
A<B (L)○ 0
VeredictoA>B ✓

9 vs 6: A>B (bit 3 decide).

Recorrido guiado (8 minutos)

  1. 1
    Mirá el estado inicial: 9 contra 6, sin signo.

    9 = 1001 y 6 = 0110. El bit 3 (1 contra 0) ya difiere: decide A > B. Las tres columnas de la derecha están en gris: nadie las mira.

  2. 2
    Apretá «6 vs 7».

    0110 contra 0111: los bits 3, 2 y 1 empatan (turquesa) y recién el bit 0 decide A < B. Es el caso más lento: todos los E de arriba tienen que valer 1 para dejar pasar la decisión.

  3. 3
    Apretá «7 vs 7».

    Los cuatro bits empatan: E = 1, y G y L valen 0. Nadie decide porque no hay diferencia.

  4. 4
    Apretá «8 vs 7».

    1000 contra 0111: el bit 3 decide A > B aunque los otros tres estén «al revés». El bit alto manda sobre todo lo demás junto.

  5. 5
    Con «15 vs 1», alterná entre «Sin signo» y «Con signo».

    Sin signo, 1111 > 0001. Con signo se invierte el bit 3 (queda 0111 contra 1001), decide el bit 3 y el veredicto pasa a A < B: −1 < 1. Los bits no cambiaron, cambió la lectura.

  6. 6
    Con «3 vs 13», repetí el cambio.

    Sin signo, 3 < 13; con signo, 13 es −3 y 3 > −3. El orden se invirtió otra vez.

  7. 7
    Pasá a «Solo igualdad» y poné A = 9, B = 11.

    1001 contra 1011 difieren solo en el bit 1. La NOR de los XOR da E = 0, pero este modo no sabe quién es mayor: G y L ni se calculan.

  8. 8
    Barrí los deslizadores con muchos pares.

    En los modos con magnitud, exactamente una de G, E y L vale 1, y la última línea del estado verifica el resultado contra el operador de comparación del lenguaje y contra las ecuaciones de suma de productos. Debe coincidir siempre.

Preguntas para pensar

  1. Con 6 contra 7, ¿qué bit decide y por qué hace falta que los tres de arriba empaten?
  2. Con 15 contra 1, ¿qué dice cada modo y por qué?
  3. ¿Por qué el modo «solo igualdad» no entrega G ni L?
  4. De los 256 pares de 4 bits, ¿cuántos dan A = B y cuántos A > B?
Ver respuestas sugeridas
  1. El bit 0 (0 contra 1). Los bits 3, 2 y 1 tienen que empatar para que el bit 0 tenga la última palabra; si uno de ellos difiriera, decidiría él.
  2. Sin signo A > B (15 > 1). Con signo A < B (−1 < 1): los mismos bits, otra lectura.
  3. La NOR de los XOR solo sabe si algún bit difiere, no cuál ni hacia dónde. Para saber quién es mayor hace falta ver cuál es el bit más alto que difiere y qué valor tiene.
  4. 16 pares iguales (A = B) y 120 con A > B (y 120 con A < B): 16 + 120 + 120 = 256.

08 · Comparar en código

Un bit, N bits, igualdad, signo, el 85, ordenar y mantener un estado

Los bloques verifican el comparador de un bit, comparan desde el bit alto y con las ecuaciones de suma de productos contra el operador del lenguaje en las 256 parejas, arman la igualdad con XOR y NOR (y con constante), comparan con signo con el truco del bit invertido y con los flags de la resta, modelan la cascada del 74HC85 para 8 y 12 bits, construyen una red de ordenamiento y simulan un termostato con histéresis.

Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.

Paso 1: el comparador de un bit

from itertools import product


def comparador1(a, b):
    g = a & (1 - b)
    l = (1 - a) & b
    e = 1 - (g | l)                       # NOR de G y L
    return g, e, l


print(" A B | G E L")
ok = True
for a, b in product((0, 1), repeat=2):
    g, e, l = comparador1(a, b)
    ok = ok and (g + e + l == 1) and (e == int(a == b)) and (g == int(a > b)) and (l == int(a < b))
    print(f" {a} {b} | {g} {e} {l}")
print("exactamente una salida vale 1 en las 4 filas, y coincide con >, == y <:", ok)
print("puertas: 2 NOT + 2 AND + 1 NOR = 5 (E sale de la NOR de G y L)")

En cada fila hay una sola salida en 1 y coincide con los operadores del lenguaje. E se obtiene sin XNOR: es la NOR de G y L.

Paso 2: N bits desde el bit más alto

from itertools import product


def msb_primero(a, b, n=4):
    for i in range(n - 1, -1, -1):
        ai, bi = (a >> i) & 1, (b >> i) & 1
        if ai != bi:
            return ("A>B" if ai else "A<B"), i
    return "A=B", None


def ecuaciones(a, b, n=4):
    g = [(a >> i) & ~(b >> i) & 1 for i in range(n)]
    l = [~(a >> i) & (b >> i) & 1 for i in range(n)]
    e = [1 - (g[i] | l[i]) for i in range(n)]
    G = L = 0
    previo = 1                              # todos los bits más altos empatan
    for i in range(n - 1, -1, -1):
        G |= previo & g[i]
        L |= previo & l[i]
        previo &= e[i]
    return G, previo, L                       # previo = E3·E2·E1·E0 al terminar


for a, b in ((9, 6), (5, 9), (6, 7), (7, 7), (8, 7)):
    v, i = msb_primero(a, b)
    extra = f"decide el bit {i}" if i is not None else "empatan los cuatro bits"
    print(f"{a:2d} vs {b:2d} ({a:04b} vs {b:04b}): {v}   {extra}")

ok = True
cuenta = {"A>B": 0, "A=B": 0, "A<B": 0}
for a, b in product(range(16), repeat=2):
    v, _ = msb_primero(a, b)
    esperado = "A>B" if a > b else "A=B" if a == b else "A<B"
    ok = ok and v == esperado and ecuaciones(a, b) == (int(a > b), int(a == b), int(a < b))
    cuenta[v] += 1
print()
print("el recorrido desde el MSB y las ecuaciones coinciden con > == < en las 256 parejas:", ok)
print("cuántos pares de cada tipo:", cuenta)

Las cinco comparaciones de la tabla: 9 vs 6 decide el bit 3, 6 vs 7 decide el bit 0 y 7 vs 7 empata. El recorrido y las ecuaciones coinciden con los operadores en las 256 parejas, y la cuenta es 120 con A>B, 16 con A=B y 120 con A<B.

Paso 3: igualdad y comparación con una constante

from itertools import product


def igual_xor_nor(a, b, n=4):
    diferencias = [((a >> i) ^ (b >> i)) & 1 for i in range(n)]       # un XOR por bit
    return 1 - int(any(diferencias))                                  # NOR de todos


def password_ok(x):
    a3, a2, a1, a0 = (x >> 3) & 1, (x >> 2) & 1, (x >> 1) & 1, x & 1
    return a3 & (1 - a2) & a1 & (1 - a0)               # AND con dos inversores: sin XOR


def igual_a_constante(x, k, n=4):
    t = 1
    for i in range(n):
        bit = (x >> i) & 1
        t &= bit if (k >> i) & 1 else 1 - bit
    return t


print("XOR + NOR coincide con == en las 256 parejas:",
      all(igual_xor_nor(a, b) == int(a == b) for a, b in product(range(16), repeat=2)))
print("password 1010 con un AND-4 y dos NOT, valores que abren:", [x for x in range(16) if password_ok(x)])
print("igual a una constante = AND de literales, para las 256 parejas (x, k):",
      all(igual_a_constante(x, k) == int(x == k) for x in range(16) for k in range(16)))

print()
print("bits  XOR  NOR4  AND2  total")
for n in (4, 8, 16, 32):
    k = -(-n // 4)                       # cuántas NOR de 4 entradas hacen falta
    print(f"{n:4d}  {n:3d}  {k:4d}  {k - 1:4d}  {n + k + (k - 1):5d}")

XOR más NOR coincide con la igualdad. Con la constante 1010, la contraseña se reduce a un AND con dos inversores y solo abre con el 10. La tabla de costos da 5, 11, 23 y 47 puertas para 4, 8, 16 y 32 bits.

Paso 4: con signo, sin signo y la resta

from itertools import product


def completo(a, b, cin):
    return a ^ b ^ cin, (a & b) | (a & cin) | (b & cin)


def restar(a, b, n=4):
    mascara = (1 << n) - 1
    be, cin, s, car = (~b) & mascara, 1, 0, []
    for i in range(n):
        si, cin = completo((a >> i) & 1, (be >> i) & 1, cin)
        s |= si << i
        car.append(cin)
    return s, car[n - 1], (s >> (n - 1)) & 1, car[n - 2] ^ car[n - 1]    # S, C, N, V


def acarreo_final(a, b, cin, n=4):
    c = cin
    for i in range(n):
        _, c = completo((a >> i) & 1, (b >> i) & 1, c)
    return c


con_signo = lambda x: x - 16 if x >= 8 else x
ok = {"C = 0 <=> A < B sin signo": True, "N != V <=> A < B con signo": True,
      "invertir el bit 3": True, "acarreo de A + ~B = (A > B)": True, "acarreo con +1 = (A >= B)": True}
for a, b in product(range(16), repeat=2):
    s, c, n_flag, v = restar(a, b)
    ok["C = 0 <=> A < B sin signo"] &= (1 - c) == int(a < b)
    ok["N != V <=> A < B con signo"] &= (n_flag ^ v) == int(con_signo(a) < con_signo(b))
    ok["invertir el bit 3"] &= int((a ^ 8) < (b ^ 8)) == int(con_signo(a) < con_signo(b))
    ok["acarreo de A + ~B = (A > B)"] &= acarreo_final(a, (~b) & 15, 0) == int(a > b)
    ok["acarreo con +1 = (A >= B)"] &= acarreo_final(a, (~b) & 15, 1) == int(a >= b)
for nombre, valor in ok.items():
    print(f"{nombre:<32} {valor}")

simbolo = lambda x, y: ">" if x > y else "=" if x == y else "<"
print()
print("  A     B     sin signo      con signo")
for a, b in ((15, 1), (8, 7), (3, 13)):
    print(f"{a:04b}  {b:04b}   {a:2d} {simbolo(a, b)} {b:2d}     {con_signo(a):2d} {simbolo(con_signo(a), con_signo(b))} {con_signo(b):2d}")

Las cinco comprobaciones dan True en las 256 parejas. El acarreo de A + ~B es A>B (y con el +1, A≥B), C=0 es A<B sin signo, N≠V es A<B con signo, e invertir el bit 3 de ambos convierte la comparación con signo en una sin signo. 15 vs 1 es 15>1 sin signo y −1<1 con signo.

Paso 5: el 74HC85 y su cascada

import random


def hc85(a, b, ig=0, ie=1, il=0):
    # a, b: palabras de 4 bits. (ig, ie, il): entradas de cascada. Devuelve (QA>B, QA=B, QA<B)
    if a > b:
        return 1, 0, 0
    if a < b:
        return 0, 0, 1
    return ig, ie, il                  # nibbles iguales: manda la cascada (se asume válida)


def comparar8(a, b):
    bajo = hc85(a & 15, b & 15, 0, 1, 0)         # primer chip: IA=B = 1 y las otras en 0
    return hc85(a >> 4, b >> 4, *bajo)           # salidas del bajo -> entradas del alto


def comparar12(a, b):
    r = (0, 1, 0)
    for k in range(3):
        r = hc85((a >> (4 * k)) & 15, (b >> (4 * k)) & 15, *r)
    return r


esperado = lambda a, b: (int(a > b), int(a == b), int(a < b))
print("A5 vs A7 (los nibbles altos empatan):", comparar8(0xA5, 0xA7))
print("F0 vs 0F (manda el chip alto):       ", comparar8(0xF0, 0x0F))
print("3C vs 3C:                            ", comparar8(0x3C, 0x3C))
print()
print("dos 85 = comparador de 8 bits, las 65536 parejas:",
      all(comparar8(a, b) == esperado(a, b) for a in range(256) for b in range(256)))
rnd = random.Random(5)
muestra = [(rnd.getrandbits(12), rnd.getrandbits(12)) for _ in range(20000)]
print("tres 85 = comparador de 12 bits, 20000 parejas al azar:",
      all(comparar12(a, b) == esperado(a, b) for a, b in muestra))
print("con el mismo nibble alto y bajo distinto, el bajo decide:",
      comparar12(0x5A3, 0x5A4), "(A < B)")

A5 vs A7 da (0, 0, 1): los nibbles altos empatan y manda el bajo. F0 vs 0F da (1, 0, 0): manda el chip alto aunque el bajo diga lo contrario. Dos 85 aciertan las 65536 parejas de 8 bits y tres aciertan 12 bits al azar. La cascada válida es una sola entrada en 1 por vez.

Paso 6: compare-exchange y una red de ordenamiento

from itertools import product


def compare_exchange(v, i, j):
    if v[i] > v[j]:                         # un comparador decide; dos multiplexores intercambian
        v[i], v[j] = v[j], v[i]


RED4 = [(0, 1), (2, 3), (0, 2), (1, 3), (1, 2)]       # cinco comparadores, siempre el mismo orden


def ordenar4(v):
    v = list(v)
    for i, j in RED4:
        compare_exchange(v, i, j)
    return v


print("ordena las 16 entradas de ceros y unos:",
      all(ordenar4(b) == sorted(b) for b in product((0, 1), repeat=4)))
print("ordena las 256 entradas de 4 valores (con repetidos):",
      all(ordenar4(p) == sorted(p) for p in product(range(4), repeat=4)))
print("ejemplo [3, 1, 4, 2] ->", ordenar4([3, 1, 4, 2]))

w = 8
print()
print(f"con palabras de {w} bits: {len(RED4)} comparadores de {w} bits + {len(RED4) * 2 * w} multiplexores 2:1")
print(f"equivale a {len(RED4) * 2 * w // 4} chips 74HC157 (cuádruple multiplexor 2:1)")

Cinco celdas compare-exchange ordenan cuatro valores, comprobado con las 16 entradas de ceros y unos y con las 256 de cuatro valores. [3, 1, 4, 2] sale [1, 2, 3, 4]. Con palabras de 8 bits son 5 comparadores y 80 multiplexores 2:1, unos 20 chips de cuatro.

Paso 7: un termostato con histéresis

def sin_histeresis(temps, consigna):
    return [1 if t < consigna else 0 for t in temps]


def con_histeresis(temps, bajo, alto, inicial=0):
    estado, salida = inicial, []
    for t in temps:
        if t < bajo:
            estado = 1                      # el comparador L con el umbral bajo: SET
        elif t > alto:
            estado = 0                      # el comparador G con el umbral alto: RESET
        salida.append(estado)               # entre los dos umbrales: el latch mantiene el estado
    return salida


def cambios(estados):
    return sum(1 for x, y in zip(estados, estados[1:]) if x != y)


temps = [10, 8, 7, 5, 6, 8, 9, 10, 8, 7]
estados = con_histeresis(temps, 6, 9)
print("T:        ", *[f"{t:2d}" for t in temps])
print("calefactor", *[" 1" if e else " 0" for e in estados])

print()
ruidosa = [8, 7, 6, 7, 6, 7, 6, 8]            # temperatura que oscila alrededor de 7
a = sin_histeresis(ruidosa, 7)
b = con_histeresis(ruidosa, 7, 8)
print("un solo umbral:  ", a, "->", cambios(a), "conmutaciones")
print("con histéresis:  ", b, "->", cambios(b), "conmutación")

Con umbrales 6 y 9, el calefactor se enciende al bajar de 6 y se apaga al pasar de 9; entre ambos mantiene el estado. Con una temperatura que oscila alrededor de 7, un solo umbral conmuta 6 veces y la histéresis (7 y 8) solo una.

09 · Analogía de programador

Orden lexicográfico y comparación de tres vías

El mismo concepto, en dos mundos.
En softwareEn el comparador
Comparar strings: la primera diferencia decideEl primer bit (desde el más alto) que difiere decide
Un cmp(a, b) o el operador <=> de tres víasLas tres salidas G, E y L, solo una en 1
El enum Ordering con Less, Equal, GreaterUna codificación one-hot de tres estados
Una cadena de else if con evaluación en cortocircuitoLos E de los bits altos como puertas que dejan pasar la decisión de abajo
memcmp, que compara bytes en orden de significanciaComparar desde el MSB
a == b frente a a < bIgualdad: XOR y NOR, barata. Magnitud: cadena de acarreo, más cara
Comparar int con unsigned en CInvertir (o no) el bit de signo antes de comparar
Un swap condicional dentro de un ordenamientoLa celda compare-exchange: comparador y multiplexores
Un umbral con histéresis para evitar el «flapping» de una alertaDos comparadores y un latch
min y maxUn comparador y un multiplexor
  1. 1
    MSB primero = diccionario.

    La primera diferencia decide; todo lo que viene después es decorado. Por eso un comparador puede «cortar» antes que un restador.

  2. 2
    Tres salidas = un enum.

    Menor, igual y mayor son excluyentes y exhaustivos: nunca dos, nunca ninguno (salvo cascada mal conectada).

  3. 3
    Con o sin signo = tipo de dato.

    Los bits no saben si son 15 o −1. Elegir el tipo de comparación es elegir cómo se leen.

Una diferencia con el software: en un programa el cortocircuito ahorra trabajo, porque los bits de abajo ni se leen. En el circuito todas las columnas están físicamente ahí y trabajan a la vez: lo que se «ahorra» es lógica en la ecuación, no tiempo. El tiempo lo marca la ruta más larga, aquella donde los bits altos empatan y decide el último.

10 · Comprensión

Confusiones frecuentes

«El XNOR alcanza para comparar»

Sirve para la igualdad. Para saber quién es mayor hace falta G y L, o restar y mirar el acarreo. Igualdad no es comparación.

«Comparar es lo mismo con signo que sin signo»

Los bits son los mismos pero el orden no: 1111 es mayor que 0001 sin signo y menor con signo. Hay que elegir, invirtiendo el bit de signo o usando N ≠ V en vez de C.

«Se empieza por el bit menos significativo»

El que manda es el más alto. Un bit bajo solo importa cuando todos los de arriba empatan. Empezar desde el LSB da veredictos equivocados (por ejemplo, 8 contra 7).

«Comparar es restar»

Se puede (los flags de la resta dan el resultado), pero un comparador dedicado no calcula las sumas, solo el acarreo: es más barato. Y para igualdad ni siquiera hace falta el acarreo.

«El 85 funciona sin cascada conectada»

Con datos iguales, el 85 devuelve lo que digan sus entradas de cascada. Si flotan o tienen una combinación inválida, el veredicto «igual» no es confiable. Hay que fijar IA=B = 1 y las otras en 0.

«Una sola temperatura de corte alcanza»

Con un solo umbral, una medición con ruido alrededor del valor enciende y apaga el actuador sin parar. Se usan dos umbrales y un latch (histéresis).

«En la cascada manda el chip bajo porque sale primero»

Sus señales salen primero, pero el chip alto tiene la prioridad: ignora la cascada cuando sus nibbles difieren. El retardo, en cambio, se acumula chip por chip.

11 · Práctica guiada

Ejercicios de arbitraje

Ejercicio 1: termostato de 4 bits

Un calefactor se enciende cuando T es menor que la consigna 7 (0111). ¿Qué salida del comparador lo gobierna? ¿Qué pasa con T = 5, T = 7 y T = 9?

Ver solución razonada

El calefactor sigue a L (T < 7). Con T = 5, L = 1: calefactor encendido. Con T = 7, E = 1 y L = 0: apagado (el borde queda del lado «apagado» con esta regla). Con T = 9, G = 1 y L = 0: apagado. Con una temperatura que oscile cerca de 7, esta regla conmutaría sin parar: para evitarlo se agrega histéresis (Paso 7).

Ejercicio 2: una cerradura de 4 bits

Una cerradura abre con el código 1010 en cuatro interruptores. ¿Cómo la armás con puertas, y cómo cambia si el código se puede configurar con otros cuatro interruptores?

Ver solución razonada

Con un código fijo: E = A3·~A2·A1·~A0, un AND de cuatro entradas con dos inversores (no hace falta ningún XOR: comparar con una constante es un minterm). Con un código configurable: 4 XOR (uno por bit) y una NOR de cuatro entradas; E = 1 solo cuando ningún bit difiere, es decir, cuando los interruptores coinciden con el código guardado.

Ejercicio 3: comparador de 2 bits

Escribí G para A = A1A0 y B = B1B0 en suma de productos con E1, G1 y G0, y contá puertas.

Ver solución razonada

G = A1·~B1 + (A1⊙B1)·A0·~B0. Puertas: 2 NOT (para ~B1 y ~B0), 3 AND (A1·~B1, A0·~B0 y E1·G0), 1 XNOR (E1) y 1 OR: 7 puertas. Para L se espeja con ~A y B, reutilizando E1.

Ejercicio 4: con signo

Con 4 bits, comparás A = 1101 y B = 0010. ¿Qué dice cada lectura y cómo se obtiene con signo usando un comparador sin signo?

Ver solución razonada

Sin signo: 13 > 2, A > B. Con signo: −3 < 2, A < B. Se invierte el bit 3 de ambos: A pasa a 0101 (5) y B a 1010 (10); sin signo 5 < 10, A < B, el veredicto correcto con signo.

Ejercicio 5: dos 85 para 8 bits

Compará A = 1010 0101 con B = 1010 0111 con dos 74HC85 en cascada. ¿Qué dice cada chip y cuál es el resultado? ¿Qué bit decide?

Ver solución razonada

El chip bajo compara 0101 contra 0111: A < B (QA<B = 1). El chip alto compara 1010 contra 1010: empatan, así que hereda el veredicto del bajo. Resultado: QA<B = 1, A < B. El bit que decide es el bit 1 (A tiene 0, B tiene 1); el bit 2 empata (los dos tienen 1).

Ejercicio 6: ordenar cuatro valores

Aplicá la red (0,1), (2,3), (0,2), (1,3), (1,2) a [3, 1, 4, 2]. ¿Cuántas celdas compare-exchange y cómo queda el vector paso a paso?

Ver solución razonada

Cinco celdas. (0,1): [1, 3, 4, 2]. (2,3): [1, 3, 2, 4]. (0,2): 1 y 2 ya están en orden, sin cambios. (1,3): 3 y 4 en orden, sin cambios. (1,2): 3 > 2, se intercambian: [1, 2, 3, 4]. Verificalo con el Paso 6.

12 · Síntesis

Ideas para recordar

  • Comparador de un bit: G = A·~B, L = ~A·B, E = ~(G + L) = A⊙B. Cinco puertas; exactamente una salida en 1.
  • Con N bits decide el primer bit, desde el más alto, que difiere. G = G3 + E3·G2 + E3·E2·G1 + …; E es el AND de los E de cada bit.
  • Igualdad barata: un XOR por bit y una NOR de todos. Comparar con una constante es un AND de literales (un minterm; la base de un decodificador).
  • El comparador es una cadena de acarreo: el acarreo de A + ~B es A > B, y con el +1 es A ≥ B. Es la misma estructura que el acarreo anticipado.
  • Con signo y sin signo dan veredictos distintos para los mismos bits. Se resuelve invirtiendo el bit de signo de ambos, o con los flags (C = 0 sin signo, N ≠ V con signo).
  • 74HC85: 4 bits con entradas de cascada. Solo, IA=B = 1 y las otras en 0. En cascada, las salidas del chip bajo van a las entradas del alto; manda el alto cuando difiere.
  • Aplicaciones: termostato con histéresis (dos umbrales y un latch), máximo y mínimo, redes de ordenamiento (comparador más multiplexores), rangos y decodificación de direcciones.
  • Es un else-if en silicio, pero con todas las columnas trabajando a la vez: el tiempo lo marca la ruta más larga.

¿Listo para el Tema 26?

Podés avanzar si sos capaz de responder esto sin mirar:

  • Escribir G, E y L de un bit y decir cuántas puertas cuestan.
  • Explicar por qué con N bits se decide desde el más alto y trazar un ejemplo.
  • Armar un comparador de igualdad de 8 bits y simplificarlo para una constante.
  • Comparar con signo y sin signo los mismos bits, e indicar cómo se obtiene cada uno.
  • Conectar dos 74HC85 para 8 bits, con las entradas de cascada del primero.
  • Explicar la histéresis de un termostato.

Ya podés sumar y comparar. Pero a veces el problema no es el valor sino saber si llegó sano: en el próximo tema, paridad y detección de errores, un bit extra vigila al resto.