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
| A B | G (A > B) | E (A = B) | L (A < B) |
|---|---|---|---|
| 0 0 | 0 | 1 | 0 |
| 0 1 | 0 | 0 | 1 |
| 1 0 | 1 | 0 | 0 |
| 1 1 | 0 | 1 | 0 |
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.
| A | B | Bits que empatan | Decide | Veredicto |
|---|---|---|---|---|
| 9 (1001) | 6 (0110) | ninguno | bit 3 (1 contra 0) | A > B |
| 5 (0101) | 9 (1001) | ninguno | bit 3 (0 contra 1) | A < B |
| 6 (0110) | 7 (0111) | bits 3, 2 y 1 | bit 0 (0 contra 1) | A < B |
| 7 (0111) | 7 (0111) | los cuatro | nadie | A = B |
| 8 (1000) | 7 (0111) | ninguno | bit 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):
| Salida | Ecuació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.
| Bits | XOR | NOR de 4 entradas | AND de 2 entradas | Total |
|---|---|---|---|---|
| 4 | 4 | 1 | 0 | 5 |
| 8 | 8 | 2 | 1 | 11 |
| 16 | 16 | 4 | 3 | 23 |
| 32 | 32 | 8 | 7 | 47 |
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.
| En el sumador (Tema 24) | En el comparador |
|---|---|
| B se invierte (~B) y se suma a A | Hay que comparar A contra B bit a bit |
| Generate: Gi = Ai·~Bi | El bit i de A «gana» (Ai = 1 y Bi = 0) |
| Propagate: Pi = Ai ⊕ ~Bi | El 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.
| A | B | Sin signo | Con signo |
|---|---|---|---|
| 1111 | 0001 | 15 > 1: A > B | −1 < 1: A < B |
| 1000 | 0111 | 8 > 7: A > B | −8 < 7: A < B |
| 0011 | 1101 | 3 < 13: A < B | 3 > −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.
| Datos A y B | Entradas de cascada > = < | Salidas > = < |
|---|---|---|
| A > B | cualquiera | 1 0 0 |
| A < B | cualquiera | 0 0 1 |
| A = B | 1 0 0 | 1 0 0 |
| A = B | 0 1 0 | 0 1 0 |
| A = B | 0 0 1 | 0 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
- 1El 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.
- 2Sus 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.
- 3Las 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.
Árbitro de 4 bits
9 vs 6 → A>B
9 vs 6: A>B (bit 3 decide).
Recorrido guiado (8 minutos)
- 1Mirá 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.
- 2Apretá «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.
- 3Apretá «7 vs 7».
Los cuatro bits empatan: E = 1, y G y L valen 0. Nadie decide porque no hay diferencia.
- 4Apretá «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.
- 5Con «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.
- 6Con «3 vs 13», repetí el cambio.
Sin signo, 3 < 13; con signo, 13 es −3 y 3 > −3. El orden se invirtió otra vez.
- 7Pasá 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.
- 8Barrí 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
- Con 6 contra 7, ¿qué bit decide y por qué hace falta que los tres de arriba empaten?
- Con 15 contra 1, ¿qué dice cada modo y por qué?
- ¿Por qué el modo «solo igualdad» no entrega G ni L?
- De los 256 pares de 4 bits, ¿cuántos dan A = B y cuántos A > B?
Ver respuestas sugeridas
- 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.
- Sin signo A > B (15 > 1). Con signo A < B (−1 < 1): los mismos bits, otra lectura.
- 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.
- 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
| En software | En el comparador |
|---|---|
| Comparar strings: la primera diferencia decide | El primer bit (desde el más alto) que difiere decide |
Un cmp(a, b) o el operador <=> de tres vías | Las tres salidas G, E y L, solo una en 1 |
El enum Ordering con Less, Equal, Greater | Una codificación one-hot de tres estados |
Una cadena de else if con evaluación en cortocircuito | Los E de los bits altos como puertas que dejan pasar la decisión de abajo |
memcmp, que compara bytes en orden de significancia | Comparar desde el MSB |
a == b frente a a < b | Igualdad: XOR y NOR, barata. Magnitud: cadena de acarreo, más cara |
Comparar int con unsigned en C | Invertir (o no) el bit de signo antes de comparar |
Un swap condicional dentro de un ordenamiento | La celda compare-exchange: comparador y multiplexores |
| Un umbral con histéresis para evitar el «flapping» de una alerta | Dos comparadores y un latch |
min y max | Un comparador y un multiplexor |
- 1MSB primero = diccionario.
La primera diferencia decide; todo lo que viene después es decorado. Por eso un comparador puede «cortar» antes que un restador.
- 2Tres salidas = un enum.
Menor, igual y mayor son excluyentes y exhaustivos: nunca dos, nunca ninguno (salvo cascada mal conectada).
- 3Con 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.