01 · Punto de partida
Por qué mover bits
Un byte en paralelo necesita 8 hilos; el mismo byte en serie necesita uno, más una señal de reloj que indique cuándo mirarlo. Cuando los pines escasean (un microcontrolador pequeño que debe manejar 16 LED, un cable largo entre dos placas, un sensor con una sola salida de datos), la solución es enviar los bits de a uno y reconstruir la palabra del otro lado. Ese trabajo de conversión lo hace el registro de desplazamiento.
| Aspecto | Paralela | Serie |
|---|---|---|
| Hilos de datos | 8 | 1 (más reloj, y a veces una señal de carga) |
| Tiempo por byte | 1 ciclo de reloj | 8 ciclos de reloj |
| Costo en pines y cables | Alto | Bajo |
| Sensibilidad a la longitud del cable | Alta (los bits deben llegar juntos) | Menor |
| Circuito necesario | Registro paralelo (tema 13) | Registro de desplazamiento |
El precio de la serie es el tiempo: lo que paralelo cuesta un ciclo, serie lo cuesta tantos como bits tenga la palabra. Para un programador es la diferencia entre pasar un array por referencia y recorrerlo elemento por elemento.
02 · Estructura
La cadena de flip-flops
La construcción es la más simple posible: Q de cada flip-flop va a la D del siguiente, y todos comparten el reloj. El dato nuevo entra por la D del primero (entrada serie) y el último entrega su Q (salida serie).
Sigamos un dato. Se envía la serie 1, 0, 1, 1 y después ceros. Al comienzo todos los flip-flops valen 0:
| Pulso | Entrada | Q0 | Q1 | Q2 | Q3 | Qué ocurrió |
|---|---|---|---|---|---|---|
| 0 | — | 0 | 0 | 0 | 0 | Estado inicial |
| 1 | 1 | 1 | 0 | 0 | 0 | Entra el primer 1 |
| 2 | 0 | 0 | 1 | 0 | 0 | El 1 avanza; entra un 0 |
| 3 | 1 | 1 | 0 | 1 | 0 | Segundo 1 en Q0; el primero en Q2 |
| 4 | 1 | 1 | 1 | 0 | 1 | El primer 1 llega al final |
| 5 | 0 | 0 | 1 | 1 | 0 | El primer 1 sale por la salida serie |
Cada bit tarda n pulsos en cruzar una cadena de n flip-flops: aparece a la salida n−1 pulsos después de entrar y en el pulso siguiente abandona la cadena. En este sentido el registro de desplazamiento es una línea de retardo digital: la señal de salida es la de entrada retrasada n períodos de reloj.
Por qué funciona sin que el dato «corra»
A primera vista, si FF1 copia lo que tiene FF0 y FF0 cambia en el mismo flanco, FF1 podría ver el dato nuevo y todos los bits se aplastarían en el mismo valor. No ocurre por el mismo motivo que hacía posible el intercambio del tema 13: la salida de un flip-flop cambia un tiempo de propagación después del flanco, mientras que la entrada del siguiente se captura en el flanco, dentro de su ventana de hold (tema 11). Cada flip-flop ve el valor anterior de su vecino. Cuando el reloj llega a los flip-flops con un retraso desigual (skew) mayor que la propagación, la cadena falla.
03 · Familias
SISO, SIPO, PISO y PIPO
Según cómo entra y sale el dato, el mismo registro se usa de cuatro formas. El nombre es la sigla de «entrada–salida» en inglés: Serial o Parallel In, Serial o Parallel Out.
| Tipo | Entrada | Salida | Uso típico | Tiempo para completar |
|---|---|---|---|---|
| SISO | Serie | Serie | Línea de retardo, regenerar una señal | n pulsos de retraso |
| SIPO | Serie | Paralelo | Recibir datos serie; sacar muchas salidas con pocos pines | n pulsos para llenar |
| PISO | Paralelo (carga) | Serie | Leer muchas entradas por un solo hilo; transmitir un byte | 1 pulso de carga + n de envío |
| PIPO | Paralelo | Paralelo | Registro de almacenamiento (tema 13) | 1 pulso |
El PIPO ya lo conocemos: es el registro paralelo, sin desplazar. Los otros tres usan la cadena. El SISO no necesita nada más; el SIPO solo agrega acceso a cada Q; el PISO agrega un selector delante de cada D que elige entre «cargar un dato» y «tomar el bit del vecino».
04 · Serie a paralelo
Serie a paralelo (SIPO)
Es la configuración que recibe. El dato llega bit a bit y, después de n pulsos, la palabra completa está disponible en las salidas Q. Hay un detalle de orden: el primer bit que entró es el que más lejos llegó. Si se envía primero el bit más significativo (MSB), queda en el último flip-flop de la cadena, y la palabra se lee con el MSB en Qn−1, como se espera.
| Pulso | Bit recibido | Contenido de la cadena (primero … último) |
|---|---|---|
| 1 | 1 | 1 0 0 0 0 0 0 0 |
| 2 | 0 | 0 1 0 0 0 0 0 0 |
| 4 | 1 | 1 1 0 1 0 0 0 0 |
| 8 | 1 | 1 0 0 0 1 1 0 1 |
Leída de derecha a izquierda, la última fila es 10110001: el byte completo. Mientras llegan los bits, las salidas paralelas muestran valores intermedios sin sentido; la palabra solo es válida después del pulso n. Por eso los sistemas que usan un SIPO agregan un segundo registro (de almacenamiento) que copia la palabra completa de una vez: las salidas finales no cambian mientras se desplaza. Ese es el principio del 74HC595 del tema 15.
05 · Paralelo a serie
Paralelo a serie (PISO)
Es la configuración que envía. Delante de cada D se coloca un selector controlado por una señal de carga/desplazamiento (LOAD / SHIFT): si vale LOAD, cada flip-flop toma su entrada paralela; si vale SHIFT, toma la salida del vecino. Es el mismo selector de la habilitación del tema 13, con otra entrada.
- Pulso de carga. Con LOAD = 1, un flanco copia los 8 bits paralelos en los 8 flip-flops. La palabra queda guardada.
- Pulsos de desplazamiento. Con LOAD = 0, cada flanco hace avanzar la palabra una posición. El bit de la salida serie va cambiando: primero el que estaba en el extremo, después el siguiente, hasta el último.
Una transmisión completa de un byte son 1 + 8 = 9 pulsos (o 8 si el primer bit se toma directamente del flip-flop de salida, sin esperar). Hay chips que implementan la carga de forma asíncrona (actúa sin reloj) y otros de forma síncrona (necesita un flanco): conviene leer la tabla de función del que se use.
El dato que sale «sobra» o «vuelve»
Cuando el bit llega al final de la cadena y sale, el registro se va llenando de ceros por la entrada serie (si ésta se deja a 0). Al cabo de n pulsos, el PISO queda vacío. Si en cambio la salida serie se conecta de vuelta a la entrada serie, los bits circulan y no se pierden: es una rotación, tema de la sección siguiente.
06 · Dirección
Izquierda, derecha y rotación
Si se colocan selectores en cada D con tres opciones (el vecino de la izquierda, el de la derecha o el valor propio) y un camino de carga paralela, se obtiene un registro universal como el 74HC194 de 4 bits. Dos pines de modo (S1, S0) eligen la operación en cada flanco:
| S1 | S0 | Operación | Efecto en un flanco |
|---|---|---|---|
| 0 | 0 | Retener | Cada FF conserva su valor |
| 0 | 1 | Desplazar a la derecha | QA ← entrada serie derecha; QB ← QA; … |
| 1 | 0 | Desplazar a la izquierda | QD ← entrada serie izquierda; QC ← QD; … |
| 1 | 1 | Carga paralela | QA..D ← entradas A..D |
Desplazar es multiplicar o dividir por dos
En binario, mover todos los bits una posición hacia la izquierda y entrar un 0 por la derecha multiplica por 2; hacia la derecha, entrando un 0 por la izquierda, divide por 2 (con descarte del resto). Es lo que hace el operador << y >> de los lenguajes de programación, y lo que implementa el hardware de un procesador con un registro de desplazamiento.
| Operación | Resultado | Valor | Bit saliente |
|---|---|---|---|
| Original | 00010110 | 22 | — |
| Izquierda (×2) | 00101100 | 44 | 0 |
| Derecha (÷2) | 00001011 | 11 | 0 |
| Derecha otra vez | 00000101 | 5 | 1 (el resto) |
Si el bit que sale por el extremo es un 1, hay desbordamiento al multiplicar (el resultado no cabe en 8 bits) o un resto al dividir. Por ejemplo, 200 × 2 en 8 bits daría 144, porque el 1 del bit más alto se perdió.
Rotación
Si el bit que sale por un extremo se conecta a la entrada serie del otro, el desplazamiento se convierte en rotación: nada se pierde y el patrón de bits circula. Rotar un registro con un solo 1 genera una luz que «corre» por una fila de LED; con un patrón más complejo, una secuencia repetitiva. Son los contadores en anillo y Johnson del tema 21.
07 · Tiempos
Tiempos y orden de los bits
Un enlace serie con un registro necesita acordar tres cosas entre emisor y receptor: cuántos bits, en qué orden y cuándo mirar cada uno.
- Cantidad de pulsos: si el receptor recibe un pulso menos o uno más que el emisor, la palabra se corre una posición. No hay aviso: el resultado es simplemente otro número (el laboratorio de código lo muestra).
- Orden: MSB primero o LSB primero. Ambos existen (SPI usa casi siempre MSB primero; UART envía el LSB primero). Si el emisor y el receptor no coinciden, el byte llega con los bits invertidos de lugar.
- Cuándo mirar: el dato debe estar estable alrededor del flanco que lo captura, con setup y hold respetados. En un enlace corto, el emisor cambia el dato con el flanco descendente y el receptor lo captura con el ascendente.
Velocidad y duración
Con un reloj de frecuencia f, enviar una palabra de n bits lleva n / f. Por ejemplo, un byte a 1 MHz tarda 8 µs; 16 registros de 8 bits encadenados (128 bits) a la misma frecuencia necesitan 128 µs, unos 7800 actualizaciones por segundo. La cadena larga paga con tiempo lo que ahorra en pines.
El reloj máximo de una cadena lo fija el mismo cálculo del tema 13 (propagación + setup + skew), con la ventaja de que entre dos flip-flops consecutivos no hay lógica, por lo que los registros de desplazamiento suelen aguantar las frecuencias más altas del chip.
08 · El desplazamiento en código
Modelar, convertir y detectar errores
Los bloques reproducen la cadena paso a paso, convierten un byte de paralelo a serie y de vuelta, comparan el desplazamiento con la multiplicación por dos y la rotación, y muestran qué pasa cuando el receptor recibe una cantidad de pulsos distinta a la esperada.
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: la cadena de cuatro flip-flops
class Desplazador:
"""Registro de desplazamiento de n bits. q[0] es el primer flip-flop (donde entra el dato)."""
def __init__(self, n=4):
self.q = [0] * n
def flanco(self, entrada):
saliente = self.q[-1]
self.q = [entrada] + self.q[:-1] # cada FF toma lo que tenía el anterior ANTES del flanco
return saliente
r = Desplazador(4)
datos = [1, 0, 1, 1, 0, 0, 0, 0]
print("pulso entrada Q0 Q1 Q2 Q3 salida")
for i, d in enumerate(datos, 1):
s = r.flanco(d)
print(f"{i:3d} {d} {' '.join(str(b) for b in r.q).replace(' ', ' ')} {s}")
El primer 1 entra en el pulso 1 y sale de la cadena en el pulso 5: cuatro flip-flops retrasan la señal cuatro pulsos. Entre medio recorre Q0, Q1, Q2 y Q3. La columna «salida» es el bit que abandona Q3 en cada pulso; los demás son los ceros del estado inicial. Probá con una cadena de 6 flip-flops y verificá que la salida se retrasa dos pulsos más.
Paso 2: paralelo a serie a paralelo
def piso(byte, n=8):
"""Carga paralela y devuelve los bits en serie, primero el más significativo."""
q = [(byte >> (n - 1 - i)) & 1 for i in range(n)] # q[0] = MSB
salida = []
for _ in range(n):
salida.append(q[0])
q = q[1:] + [0] # desplazamiento hacia la salida
return salida
def sipo(bits, n=8):
q = [0] * n
for b in bits:
q = q[1:] + [b] # el último bit recibido queda en el LSB
return sum(b << (n - 1 - i) for i, b in enumerate(q))
for byte in (0xA5, 0x3C, 0xFF):
linea = piso(byte)
print(f"0x{byte:02X} -> serie {''.join(map(str, linea))} -> paralelo 0x{sipo(linea):02X}")
Los tres bytes viajan por un solo hilo, un bit por pulso, y se reconstruyen idénticos: 0xA5 como 10100101, 0x3C como 00111100 y 0xFF como 11111111. Es el enlace completo de un PISO y un SIPO conectados por dato y reloj. Cambiá n a 4 y mandá solo el nibble bajo.
Paso 3: desplazar, multiplicar y rotar
def izquierda(v, entrada=0, n=8):
saliente = (v >> (n - 1)) & 1
return ((v << 1) & (2 ** n - 1)) | entrada, saliente
def derecha(v, entrada=0, n=8):
saliente = v & 1
return (v >> 1) | (entrada << (n - 1)), saliente
v = 0b00010110 # 22
print(f"inicial {v:08b} = {v}")
a, _ = izquierda(v)
print(f"izquierda (x2) {a:08b} = {a}")
b, _ = derecha(v)
print(f"derecha (/2) {b:08b} = {b}")
x = 0b11000001
print("rotacion a la izquierda:")
for i in range(4):
print(f" paso {i}: {x:08b}")
x, s = izquierda(x, 0)
x |= s # el bit saliente vuelve a entrar
print("desbordamiento: 200 x 2 =", izquierda(200)[0], "(se perdio el bit saliente", izquierda(200)[1], ")")
22 desplazado a la izquierda da 44 (×2) y a la derecha 11 (÷2). La rotación de 11000001 recorre 10000011, 00000111 y 00001110: el 1 de la izquierda reaparece por la derecha en lugar de perderse. Con 200 × 2 el resultado es 144, no 400: el bit saliente (1) es el desbordamiento.
Paso 4: errores de sincronización
def recibir(trama, n=8):
q = [0] * n
for b in trama:
q = q[1:] + [b]
return sum(b << (n - 1 - i) for i, b in enumerate(q))
byte = 0xB1
bits = [(byte >> (7 - i)) & 1 for i in range(8)]
casos = {
"8 pulsos (correcto)": bits,
"7 pulsos (falta uno)": bits[:-1],
"9 pulsos (un pulso de mas)": bits + [0],
"reloj con ruido: un pulso doble": bits[:3] + [bits[2]] + bits[3:],
}
for nombre, trama in casos.items():
r = recibir(trama)
print(f"{nombre:34s} recibe 0x{r:02X} ({'OK' if r == byte else 'ERROR'})")
print("bits invertidos (LSB primero):", f"0x{recibir(bits[::-1]):02X}")
Solo la trama de 8 pulsos reconstruye 0xB1. Con 7 pulsos llega 0x58 (todo corrido un lugar a la derecha, con un 0 faltante), con 9 pulsos llega 0x62 (el MSB se perdió) y con un pulso doble en el reloj llega 0x71. Si emisor y receptor discuten el orden, el byte 0xB1 aparece como 0x8D. Ningún error produce un aviso: el dato llega, pero es otro.
La enseñanza es la misma del taller anterior: un bit de más o de menos no rompe nada visible. Por eso los protocolos serie agregan señales de sincronía (bit de inicio, selección de chip, tramas con longitud fija) que marcan dónde empieza la palabra.
09 · Exploración interactiva
El laboratorio: registro universal
El simulador reproduce un registro universal de 8 bits. Con el selector de modo elegís qué hace el próximo flanco: retener, desplazar a la derecha (Q7 → Q0, el bit nuevo entra por Q7), desplazar a la izquierda (Q0 → Q7, el bit nuevo entra por Q0) o cargar el valor paralelo. La casilla de rotación conecta el bit saliente con la entrada serie, y la tabla registra los últimos pulsos. Los resultados muestran el valor sin signo, para ver el efecto de multiplicar y dividir por dos.
Registro de desplazamiento universal de 8 bits
Registro en 00000000, modo retener. Elegí «Carga paralela» y presioná «Pulso de reloj».
| N.º | Operación | Antes | Después | Bit saliente |
|---|---|---|---|---|
| Sin pulsos registrados. | ||||
Recorrido guiado
- Elegí «Carga paralela» con 10110001 y presioná «Pulso de reloj»: el registro vale 10110001 (177). Los ocho bits se cargan a la vez.
- Pasá a «Desplazar a la derecha» con entrada serie = 0 y pulsá: 01011000 (88). Es la mitad entera de 177 y el 1 que salió se cuenta como perdido.
- Pulsá una vez más: 00101100 (44). Cada pulso divide por dos.
- Pasá a «Desplazar a la izquierda» y pulsá: 01011000 (88). Multiplicar por 2 recupera el valor anterior, que sólo coincide mientras no se haya perdido ningún 1.
- Seguí pulsando a la izquierda hasta que un 1 salga por Q7: el valor deja de ser el doble. Es el desbordamiento.
- Reiniciá, cargá 00000001 y activá «Rotación»: con desplazamiento a la izquierda el 1 recorre las ocho posiciones y vuelve a Q0 en el pulso 8. Nada se pierde.
- Cargá 00000000, poné entrada serie = 1 y desplazá a la derecha ocho veces: el registro se llena de unos de a uno. Con la entrada en 0 se vacía de la misma forma.
- En «Retener» el reloj llega pero el registro no cambia: igual que EN = 0 del tema 13.
Desafío: dividir por dos con signo
Con una entrada serie fija en 0 el desplazamiento a la derecha divide números sin signo. Para números con signo en complemento a dos hay que repetir el bit más alto en lugar de entrar un 0 (desplazamiento aritmético). Probalo: cargá 11110000 (−16 en complemento a dos), desplazá a la derecha con entrada serie = 1 y obtenés 11111000 (−8). Con entrada serie = 0 resultaría 01111000 (+120), un valor sin relación con la mitad de −16.
10 · Comprensión
Confusiones frecuentes
«Todos los flip-flops reciben el dato nuevo a la vez»
Solo el primero lo recibe; los demás reciben el valor que tenía su vecino. El dato nuevo avanza una posición por flanco, no se copia a toda la cadena.
«El primer bit enviado queda en la primera salida»
Queda en la última: es el que más lejos llegó. Si se mandó el MSB primero, ocupa la posición más alta una vez completada la recepción.
«Las salidas paralelas de un SIPO son válidas en todo momento»
Solo después de los n pulsos. Mientras se desplaza, contienen una mezcla de bits viejos y nuevos. Por eso se agrega un registro de salida que copia la palabra completa.
«Un pulso de más no causa problema: sobra un bit»
Corre toda la palabra una posición y descarta el bit más antiguo. El resultado es un número distinto, sin ninguna señal de error.
«Desplazar a la izquierda siempre multiplica por dos»
Solo mientras el bit que sale sea 0. Si sale un 1, el resultado ya no cabe en el ancho del registro y se trunca.
«Rotar y desplazar son lo mismo»
Desplazar descarta el bit saliente y entra un valor fijo; rotar reinyecta el bit saliente. Rotar conserva la información, desplazar no.
«Serie y paralelo tardan lo mismo»
La serie tarda n ciclos por palabra de n bits. Se gana en pines y se pierde en velocidad.
«El registro de desplazamiento necesita lógica entre etapas»
No: la salida Q de cada etapa va directa a la D de la siguiente. Eso lo hace uno de los circuitos secuenciales más veloces. La lógica aparece solo en el PISO (selector de carga) y en el registro universal.
11 · Práctica guiada
Predecí antes de simular
1. Seguir una cadena
Una cadena de 4 flip-flops arranca en 0000 (Q0 Q1 Q2 Q3). Se aplican en cuatro pulsos las entradas 1, 1, 0, 1. ¿Qué contiene después de cada pulso?
Ver solución
Pulso 1: 1000. Pulso 2: 1100. Pulso 3: 0110. Pulso 4: 1011. Cada pulso agrega el nuevo bit por la izquierda (Q0) y desplaza los demás una posición hacia Q3.
2. Retardo
Con un reloj de 10 MHz y un registro de 8 flip-flops usado como línea de retardo, ¿cuánto retrasa la señal?
Ver solución
El período es 100 ns. Retrasa 8 períodos = 800 ns. Cambiando la frecuencia del reloj o tomando la salida de otro flip-flop de la cadena se ajusta el retardo en pasos de 100 ns.
3. Tiempo de transmisión
Un microcontrolador actualiza 24 LED con tres registros de 8 bits encadenados y un reloj de 2 MHz. ¿Cuánto dura una actualización y cuántas por segundo caben?
Ver solución
Son 24 bits a 2 MHz: 24 / 2 000 000 = 12 µs por actualización, es decir, unas 83 000 actualizaciones por segundo. Sobra ancho de banda para una pantalla multiplexada.
4. Multiplicar por desplazamiento
¿Cómo se multiplica por 10 usando solo desplazamientos y sumas? Calculá 7 × 10.
Ver solución
10 = 8 + 2, así que x·10 = (x ≪ 3) + (x ≪ 1). Con x = 7: 56 + 14 = 70. Es la forma en que un procesador sin multiplicador evita la multiplicación.
5. Bit saliente
En un registro de 8 bits vale 10010110 (150). Se desplaza una vez a la izquierda con entrada 0. ¿Cuál es el resultado, qué bit sale y por qué no es 300?
Ver solución razonada
El resultado es 00101100 (44). Sale un 1 por el extremo izquierdo. 300 necesita 9 bits (100101100): el bit más significativo se perdió, y 300 − 256 = 44. Es el desbordamiento de una multiplicación por 2.
6. Diagnóstico
Un SIPO de 8 bits recibe el byte 0x2D (00101101), pero las salidas muestran 0x5A. El emisor y el receptor usan el mismo reloj. ¿Cuál es la causa más probable?
Ver solución razonada
0x5A = 01011010 es 00101101 corrido una posición a la izquierda con un 0 entrando por la derecha: el receptor recibió un pulso de más (el primer bit fue desplazado una posición adicional). Hay que revisar el conteo de pulsos y la señal que marca el comienzo de la palabra; una causa frecuente es un reloj con ruido o un pulso extra al iniciar la transmisión.
12 · Síntesis
Ideas para recordar
- Un registro de desplazamiento conecta la Q de cada flip-flop con la D del siguiente; con un reloj común, todos los bits avanzan una posición por flanco.
- Funciona porque cada flip-flop captura el valor anterior de su vecino: la propagación es más larga que el hold.
- SISO es una línea de retardo de n períodos; SIPO convierte serie en paralelo; PISO convierte paralelo en serie con un selector de carga; PIPO es el registro de almacenamiento.
- En un SIPO la palabra es válida solo después de los n pulsos; un registro de salida evita mostrar valores intermedios.
- Enviar n bits lleva n / f; se ahorran pines y se paga con tiempo.
- Desplazar a la izquierda multiplica por 2 y a la derecha divide por 2; el bit saliente indica desbordamiento o resto. Rotar reinyecta el bit saliente.
- Un registro universal elige con S1 S0 entre retener, desplazar a derecha, desplazar a izquierda y carga paralela.
- Un pulso de más o de menos, o un orden de bits distinto entre emisor y receptor, produce un dato válido pero equivocado.
¿Listo para el tema 15?
Antes de avanzar, explicá cuánto tardan en cruzar una cadena de 8 flip-flops los bits de un byte, por qué las salidas de un SIPO no son confiables durante el desplazamiento y qué ocurre si el receptor cuenta un pulso de menos. Si podés justificar las tres respuestas, ya estás listo para usar un registro de desplazamiento real.
En el próximo tema armaremos el taller del 74HC595: un registro de desplazamiento de 8 bits con registro de salida y habilitación, que permite manejar ocho salidas con tres pines del microcontrolador.