← Volver al blogCodificación binaria

Código Gray explicado: por qué lo usan los codificadores rotatorios

El código Gray da a los valores adyacentes una distancia de Hamming de un bit. Conoce sus fórmulas de conversión, sus ventajas para codificadores y las restricciones de CDC que sigue necesitando una FIFO asíncrona.

DennyDenny
8 min de lectura
Chalkboard feature illustration for “Código Gray explicado: por qué lo usan los codificadores rotatorios”

En resumen: En el código Gray binario reflejado, los valores adyacentes difieren en un bit. Esta propiedad limita la ambigüedad en un límite de posición construido correctamente y resulta útil para los punteros de FIFO asíncronas. No elimina la metaestabilidad, los fallos de sensores, los transitorios combinacionales ni la necesidad de restricciones de temporización para CDC.

Un contador binario estándar de 4 bits que avanza de 01110111 a 10001000 conmuta los cuatro bits a la vez. En un diagrama de temporización idealizado, esos bits cambian simultáneamente. En silicio real —con retardos de puerta desiguales, flancos con distintas velocidades de transición y rieles de alimentación ruidosos— cambian en algún orden no especificado, lo que produce un breve parpadeo de valores intermedios como 11111111 o 00000000 en el bus. Para un registro de CPU, esto es inocuo: el valor se muestrea en un flanco de reloj después de que todo se estabilice. Para un sensor leído por un observador asíncrono, esos transitorios son lecturas reales.

El código Gray, también llamado código binario reflejado, modifica la condición de contorno: las palabras de código adyacentes difieren en un bit, por lo que un observador correctamente alineado no tiene que resolver a la vez varias transiciones de bit previstas. El único bit que está cambiando aún puede ser ambiguo, ruidoso o metaestable; por ello, el código Gray reduce una clase de error en lugar de hacer infalible la interfaz.

¿Por qué importa la adyacencia de un bit?

Considera un codificador rotatorio: el disco óptico o magnético que indica a un controlador de motor en qué ángulo está un eje. El disco tiene pistas concéntricas; cada pista aporta un bit de la palabra de posición, leído por un sensor situado en un ángulo fijo. A medida que el disco gira, el sensor observa una secuencia de valores binarios.

Si las pistas están codificadas en binario directo, el límite entre la posición 33 (011011) y la posición 44 (100100) exige que tres pistas cambien de estado en el mismo ángulo nominal. La colocación de los sensores, la geometría de las pistas y las diferencias de umbral hacen que esas transiciones no tengan por qué observarse simultáneamente. El controlador puede decodificar brevemente una palabra intermedia alejada de cualquiera de las dos posiciones adyacentes.

Codificar el mismo disco en código Gray convierte cada límite angular en una transición de un solo bit:

PosiciónBinarioGray
0000000
1001001
2010011
3011010
4100110
5101111
6110101
7111100

Observa la columna Gray. Entre dos filas adyacentes cualesquiera, exactamente un bit cambia. Entre la fila 7 y la fila 0 también cambia exactamente un bit, así que la secuencia es cíclica y de distancia unitaria. Bajo el modelo previsto de un límite a la vez, la incertidumbre de umbral queda confinada al código adyacente antiguo o nuevo. La desalineación a través de varios límites, la contaminación, las pistas dañadas, el ruido eléctrico o la decodificación de una muestra metaestable aún pueden producir un error.

La tabla de código Gray de 4 bits

El patrón se extiende de forma natural:

DecimalBinarioGray
000000000
100010001
200100011
300110010
401000110
501010111
601100101
701110100
810001100
910011101
1010101111
1110111110
1211001010
1311011011
1411101001
1511111000

El nombre «reflejado» procede de la regla de construcción: para formar el código de (n+1)(n+1) bits, toma el código de nn bits, refléjalo verticalmente, antepone un 00 a la mitad original y un 11 a la mitad reflejada. El reflejo garantiza que el límite entre las dos mitades sea una transición de un solo bit (el nuevo MSB).

Conversión de binario a Gray

La conversión de binario bb a Gray gg es una de las fórmulas más limpias de la lógica digital:

gi=bi⊕bi+1g_i = b_i \oplus b_{i+1}

con bn=0b_n = 0 para el MSB. Como expresión única:

g=b⊕(b≫1)g = b \oplus (b \gg 1)

En hardware, cada salida Gray es una XOR de bits binarios adyacentes; no hay cadena de acarreo y la profundidad lógica ideal es una etapa XOR. Eso no garantiza una salida combinacional sin transitorios mientras cambian físicamente varios bits de un contador binario. Registra el valor Gray convertido antes de tratarlo como señal de CDC. Para entender por qué XOR es el operador adecuado, vuelve a consultar el papel de la puerta XOR como detector de diferencias.

Ejemplo resuelto. Convierte el binario 10111011 a Gray.

  • g3=b3⊕0=1g_3 = b_3 \oplus 0 = 1
  • g2=b2⊕b3=0⊕1=1g_2 = b_2 \oplus b_3 = 0 \oplus 1 = 1
  • g1=b1⊕b2=1⊕0=1g_1 = b_1 \oplus b_2 = 1 \oplus 0 = 1
  • g0=b0⊕b1=1⊕1=0g_0 = b_0 \oplus b_1 = 1 \oplus 1 = 0

Resultado: Gray 11101110, que la tabla anterior confirma como la codificación del decimal 11.

Conversión de Gray a binario

La dirección inversa usa una XOR de prefijo:

bi=gi⊕gi+1⊕gi+2⊕⋯⊕gnb_i = g_i \oplus g_{i+1} \oplus g_{i+2} \oplus \dots \oplus g_n

De forma equivalente, recorriendo desde el MSB hacia abajo: bn=gnb_n = g_n y después bi=bi+1⊕gib_i = b_{i+1} \oplus g_i. Una implementación serie directa tiene profundidad XOR lineal, pero un árbol XOR de prefijo paralelo puede reducir la profundidad a costa de más cableado y puertas. No supongas que la cadena ingenua es la única implementación.

Para el ejemplo anterior, al decodificar Gray 11101110:

  • b3=g3=1b_3 = g_3 = 1
  • b2=b3⊕g2=1⊕1=0b_2 = b_3 \oplus g_2 = 1 \oplus 1 = 0
  • b1=b2⊕g1=0⊕1=1b_1 = b_2 \oplus g_1 = 0 \oplus 1 = 1
  • b0=b1⊕g0=1⊕0=1b_0 = b_1 \oplus g_0 = 1 \oplus 0 = 1

Binario recuperado: 10111011, decimal 11. Ida y vuelta sin errores.

Más allá de los codificadores: cruce de dominios de reloj

Los codificadores rotatorios son la motivación de manual, pero el uso moderno más importante del código Gray está dentro de las FPGA y los SoC: punteros de FIFO asíncronas para el cruce de dominios de reloj (CDC).

Una FIFO de doble reloj necesita que cada lado estime el puntero del otro para poder determinar el estado lleno o vacío. Enviar directamente un contador binario ordinario de varios bits a través del límite no es seguro porque un incremento puede cambiar varios bits.

Un diseño robusto de punteros Gray normalmente:

  1. mantiene el puntero de trabajo en binario para la aritmética local;
  2. convierte el puntero siguiente a Gray;
  3. registra el valor Gray en el dominio de origen;
  4. sincroniza cada bit Gray en el dominio de destino; y
  5. compara el puntero sincronizado utilizando las ecuaciones de lleno/vacío documentadas de la FIFO.

La codificación Gray implica que solo cambia un bit lógico del puntero por incremento, pero no garantiza por sí sola un CDC correcto. El bit que cambia puede violar la ventana de captura de un biestable de destino y volverse metaestable. El sesgo de enrutamiento también puede hacer que distintos bits Gray de diferentes transiciones de origen se solapen en el destino, salvo que las restricciones de implementación limiten el retardo o el sesgo del bus. Tanto AMD como Intel documentan dichas restricciones para punteros de FIFO codificados en Gray.

El puntero sincronizado también se retrasa varios relojes de destino. La lógica de lleno/vacío está diseñada para ser conservadora ante esa latencia; no es un recuento entre dominios continuamente exacto. Usa un diseño de FIFO asíncrona probado o IP de proveedor cuando la corrección sea importante.

Un contador de código Gray en hardware

Dos enfoques prácticos son:

  1. Contador binario + conversión registrada. Calcula gray_next = binary_next XOR (binary_next >> 1) y captura ambos valores siguientes en el mismo reloj de origen. La salida Gray registrada cambia de acuerdo con la secuencia de código; no expongas un convertidor no registrado alimentado por un contador binario con ondulación o sesgo como si no produjera transitorios.
  2. Máquina de estados Gray nativa. Deriva la lógica de siguiente estado que siga directamente la secuencia Gray elegida. Esto evita un registro de estado binario, pero hace menos cómoda la aritmética de incremento/decremento y de direcciones FIFO.

Para experimentar con el primer enfoque, abre la plantilla de contador binario de 4 bits, añade la red XOR y registra sus cuatro salidas. Compara los estados estables después de cada reloj. Si el simulador modela el retardo de puerta, inspecciona también la salida del convertidor no registrado durante las transiciones; puede revelar por qué importa el registro de origen.

Inconvenientes: la aritmética es incómoda

El superpoder del código Gray —las transiciones de un solo bit— tiene un precio: la aritmética en código Gray es difícil. No existe una fórmula de propagación de acarreo que funcione directamente con valores codificados en Gray. Sumar dos números Gray requiere convertir ambos a binario, sumarlos y volver a convertirlos. La multiplicación y los desplazamientos presentan el mismo problema.

Por eso, las rutas de datos aritméticas ordinarias suelen convertir el estado codificado en Gray a binario en lugar de realizar aritmética completa directamente en código Gray. La codificación es útil en límites concretos, no un sustituto universal del binario. Los mapas de Karnaugh usan el orden Gray por otro motivo: las celdas adyacentes deben diferir en una variable de entrada para que los grupos geométricos correspondan a implicantes.

Nota histórica

La codificación recibe su nombre del investigador de Bell Labs Frank Gray. Su solicitud de patente «Pulse Code Communication» se presentó en 1947 y se concedió como la patente estadounidense 2,632,058 en 1953; denomina al esquema código binario reflejado y destaca que las amplitudes representadas vecinas difieren en una posición de pulso. Las secuencias relacionadas de distancia unitaria son anteriores a la patente, por lo que es más preciso atribuir a Gray esta aplicación influyente y la línea de denominación que atribuirle la invención de todas esas secuencias.

Errores habituales

  • Suponer que la aritmética funciona. Sumar valores codificados en Gray bit a bit produce resultados sin sentido. Convierte siempre primero a binario.
  • Ignorar la convención de cero en el MSB. La fórmula de binario a Gray presupone un cero virtual por encima del MSB. Olvidarlo invierte el signo del bit alto.
  • Mezclar Gray con bucles de registros de desplazamiento. Un registro de desplazamiento estándar, como los diseños SISO/SIPO, desplaza los bits lateralmente y no conserva de extremo a extremo las propiedades de distancia unitaria. Convierte en los límites.
  • Confundir Gray con one-hot. La codificación one-hot (solo hay un bit activado) también es resistente a transitorios en otro sentido, pero tiene un ancho de O(2n)O(2^n) en vez de nn. El código Gray es la opción compacta.

Qué sigue

La guía publicada de SISO, SIPO, PISO y PIPO compara las cuatro rutas de datos habituales de los registros de desplazamiento. No uses un registro de desplazamiento ordinario como sustituto de una FIFO asíncrona: los datos relacionados de varios bits requieren un protocolo que preserve la coherencia a través del límite de reloj.

Para ver el código Gray en acción, carga la plantilla de contador binario de 4 bits, construye el convertidor, añade un registro de salida y verifica la distancia de Hamming entre valores registrados consecutivos. Después, elimina deliberadamente el registro en un modelo sensible al retardo e inspecciona el comportamiento transitorio.

Referencias principales

Convierte la idea en un circuito funcional.