그레이 코드 설명: 로터리 엔코더가 사용하는 이유
그레이 코드는 인접한 값 사이의 해밍 거리를 1비트로 만듭니다. 변환 공식, 엔코더의 이점, 비동기 FIFO에 여전히 필요한 CDC 제약을 알아봅니다.
요약: 반사 이진 그레이 코드에서는 인접한 값이 한 비트만 다릅니다. 이 성질은 올바르게 구성된 위치 경계에서의 모호성을 제한하고 비동기 FIFO 포인터에 유용합니다. 하지만 메타안정성, 센서 결함, 조합 논리 글리치, CDC 타이밍 제약의 필요성까지 없애지는 못합니다.
표준 4비트 이진 카운터가 에서 으로 진행할 때는 네 비트가 한꺼번에 바뀝니다. 이상화한 타이밍 다이어그램에서는 이 비트들이 동시에 변합니다. 하지만 게이트 지연의 불일치, 느린 에지, 전원 레일의 잡음이 있는 실제 실리콘에서는 정해지지 않은 순서로 변하며 버스에 이나 같은 중간값이 잠시 나타납니다. CPU 레지스터에서는 무해합니다. 모든 것이 안정된 뒤 클록 에지가 값을 샘플링하기 때문입니다. 그러나 비동기 관찰자가 읽는 센서에서는 이 글리치가 실제 읽기값이 됩니다.
반사 이진 코드라고도 하는 그레이 코드는 경계 조건을 바꿉니다. 인접한 코드워드는 한 비트만 다르므로, 올바르게 정렬된 관찰자는 여러 의도된 비트 전환을 동시에 판별할 필요가 없습니다. 전환 중인 한 비트도 여전히 모호하거나 잡음이 섞이거나 메타안정 상태가 될 수 있습니다. 따라서 그레이 코드는 인터페이스를 무오류로 만드는 것이 아니라 한 종류의 오류를 줄입니다.
단일 비트 인접성이 중요한 이유는?
모터 제어기에 축의 각도를 알려 주는 광학 또는 자기식 디스크인 로터리 엔코더를 생각해 봅시다. 디스크에는 동심 트랙이 있으며 각 트랙은 고정 각도에 놓인 센서가 읽는 위치 워드의 한 비트를 제공합니다. 디스크가 회전하면 센서는 이진값의 수열을 봅니다.
트랙을 일반 이진수로 인코딩하면 위치 ()에서 위치 ()로 넘어가는 경계에서 세 트랙이 같은 명목 각도에 상태를 바꿔야 합니다. 센서의 배치, 트랙의 형상, 임계값의 차이 때문에 이 전환들이 동시에 관찰된다는 보장은 없습니다. 제어기는 두 인접 위치 어느 쪽에서도 먼 중간 워드를 잠시 디코딩할 수 있습니다.
같은 디스크를 그레이 코드로 인코딩하면 모든 각도 경계가 단일 비트 전환이 됩니다.
| Position | Binary | Gray |
|---|---|---|
| 0 | 000 | 000 |
| 1 | 001 | 001 |
| 2 | 010 | 011 |
| 3 | 011 | 010 |
| 4 | 100 | 110 |
| 5 | 101 | 111 |
| 6 | 110 | 101 |
| 7 | 111 | 100 |
Gray 열을 보세요. 인접한 두 행 사이에서는 정확히 한 비트가 바뀝니다. 7행과 0행 사이에서도 정확히 한 비트가 바뀌므로, 이 수열은 순환적이고 단위 거리를 갖습니다. 한 번에 하나의 경계만 넘는다는 의도된 모델에서는 임계값의 불확실성이 이전 코드 또는 인접한 새 코드로 제한됩니다. 여러 경계를 넘는 오정렬, 오염, 트랙 손상, 전기적 잡음, 메타안정 샘플의 디코딩은 여전히 오류를 일으킬 수 있습니다.
4비트 그레이 코드 표
이 패턴은 자연스럽게 확장됩니다.
| Decimal | Binary | Gray |
|---|---|---|
| 0 | 0000 | 0000 |
| 1 | 0001 | 0001 |
| 2 | 0010 | 0011 |
| 3 | 0011 | 0010 |
| 4 | 0100 | 0110 |
| 5 | 0101 | 0111 |
| 6 | 0110 | 0101 |
| 7 | 0111 | 0100 |
| 8 | 1000 | 1100 |
| 9 | 1001 | 1101 |
| 10 | 1010 | 1111 |
| 11 | 1011 | 1110 |
| 12 | 1100 | 1010 |
| 13 | 1101 | 1011 |
| 14 | 1110 | 1001 |
| 15 | 1111 | 1000 |
“반사”라는 이름은 구성 규칙에서 왔습니다. 비트 코드를 만들려면 비트 코드를 세로로 거울처럼 뒤집고, 원래 절반 앞에는 을, 뒤집은 절반 앞에는 을 붙입니다. 이 반사는 두 절반 사이의 경계가 한 비트 전환, 즉 새 MSB의 전환이 되도록 보장합니다.
이진수에서 그레이 코드로 변환
이진수 를 그레이 코드 로 변환하는 식은 디지털 논리에서 가장 깔끔한 공식 중 하나입니다.
여기서 MSB에 대해서는 입니다. 하나의 식으로 쓰면 다음과 같습니다.
하드웨어에서 각 그레이 출력은 인접한 이진 비트 둘의 XOR 하나입니다. 자리올림 연쇄가 없고 이상적인 논리 깊이는 XOR 한 단계입니다. 그렇다고 여러 비트의 이진 카운터가 물리적으로 바뀌는 동안 조합 출력이 글리치 없이 나온다는 뜻은 아닙니다. 변환한 그레이 값을 CDC 신호로 취급하기 전에 레지스터에 저장하세요. XOR이 알맞은 연산자인 이유는 차이 검출기로서 XOR 게이트의 역할에서 다시 확인할 수 있습니다.
계산 예제. 이진수 을 그레이 코드로 변환합니다.
결과는 그레이 코드 이며, 위 표에서 십진수 11의 인코딩임을 확인할 수 있습니다.
그레이 코드에서 이진수로 변환
역방향 변환은 접두 XOR입니다.
같은 내용을 MSB에서 아래로 내려오며 쓰면 , 그다음 입니다. 직접적인 직렬 구현의 XOR 깊이는 선형이지만, 병렬 접두 XOR 트리는 배선과 게이트를 더 쓰는 대신 깊이를 줄일 수 있습니다. 단순한 연쇄만이 유일한 구현이라고 가정하지 마세요.
위 예에서 그레이 코드 을 디코딩하면 다음과 같습니다.
복원한 이진수는 , 십진수 11입니다. 왕복 변환이 정확합니다.
엔코더를 넘어: 클록 도메인 교차
로터리 엔코더는 교과서적인 동기이지만, 오늘날 그레이 코드가 가장 중요한 역할을 하는 곳은 FPGA와 SoC 내부의 클록 도메인 교차(CDC)를 위한 비동기 FIFO 포인터입니다.
듀얼 클록 FIFO에서는 각 측이 full 또는 empty 상태를 판단하기 위해 반대쪽 포인터를 추정해야 합니다. 일반적인 다중 비트 이진 카운터를 경계 너머로 직접 보내는 것은 안전하지 않습니다. 한 번 증가할 때 여러 비트가 바뀔 수 있기 때문입니다.
견고한 그레이 포인터 설계는 보통 다음과 같습니다.
- 로컬 산술을 위해 동작 포인터를 이진수로 유지합니다.
- 다음 포인터를 그레이 코드로 변환합니다.
- 소스 도메인에서 그레이 값을 레지스터에 저장합니다.
- 각 그레이 비트를 목적지 도메인으로 동기화합니다.
- FIFO에 문서화된 full/empty 방정식으로 동기화된 포인터를 비교합니다.
그레이 코딩은 증가당 논리 포인터 비트 하나만 바뀌게 하지만, 그것만으로 CDC의 정확성이 보장되지는 않습니다. 바뀌는 비트가 목적지 플립플롭의 샘플링 구간을 위반하여 메타안정 상태가 될 수 있습니다. 구현 제약이 지연이나 버스 스큐를 제한하지 않으면, 배선 스큐 때문에 서로 다른 소스 전환의 그레이 비트가 목적지에서 겹칠 수도 있습니다. AMD와 Intel 모두 그레이 코드 FIFO 포인터를 위한 이런 제약을 문서화하고 있습니다.
동기화된 포인터는 목적지 클록 여러 주기만큼 지연되기도 합니다. full/empty 논리는 이 지연 주변에서 보수적으로 동작하도록 설계되어 있으며, 도메인을 넘는 연속적으로 정확한 개수가 아닙니다. 정확성이 중요하다면 검증된 비동기 FIFO 설계나 벤더 IP를 사용하세요.
하드웨어의 그레이 코드 카운터
실용적인 접근법은 두 가지입니다.
- 이진 카운터 + 등록된 변환.
gray_next = binary_next XOR (binary_next >> 1)을 계산하고 같은 소스 클록에서 두 다음 값을 함께 캡처합니다. 등록된 그레이 출력은 코드 수열에 따라 바뀝니다. 리플 또는 스큐가 있는 이진 카운트에 연결된 등록되지 않은 변환기를 글리치가 없는 것처럼 노출하지 마세요. - 네이티브 그레이 상태 기계. 선택한 그레이 수열을 직접 따르도록 다음 상태 논리를 만듭니다. 이진 상태 레지스터를 피할 수 있지만 증가/감소와 FIFO 주소 산술은 덜 편리해집니다.
첫 번째 접근법을 실험하려면 4비트 이진 카운터 템플릿을 열고 XOR 네트워크를 추가한 뒤 네 출력을 레지스터에 저장하세요. 각 클록 뒤의 안정 상태를 비교합니다. 시뮬레이터가 게이트 지연을 모델링한다면 전환 중 등록되지 않은 변환기 출력도 살펴보세요. 왜 소스 레지스터가 중요한지 알 수 있습니다.
단점: 산술이 불편하다
그레이 코드의 강점인 단일 비트 전환에는 대가가 있습니다. 그레이 코드에서 산술 연산은 어렵습니다. 그레이 코드 값에 직접 적용되는 자리올림 전파 공식은 없습니다. 그레이 숫자 두 개를 더하려면 둘 다 이진수로 변환하고, 더한 후 다시 변환해야 합니다. 곱셈과 시프트도 마찬가지로 제대로 동작하지 않습니다.
그래서 일반 산술 데이터패스는 대개 전체 산술을 그레이 코드에서 수행하기보다 그레이 코드 상태를 이진수로 변환합니다. 이 인코딩은 특정 경계에서 유용할 뿐, 이진수를 전부 대체하는 것은 아닙니다. 카르노 맵이 그레이 순서를 쓰는 이유는 또 다릅니다. 인접한 셀은 한 입력 변수만 달라야 기하학적 그룹이 항을 의미하기 때문입니다.
역사적 메모
이 인코딩은 벨 연구소 연구원 프랭크 그레이의 이름을 땄습니다. 그의 “Pulse Code Communication” 특허 출원은 1947년에 이루어졌고 1953년에 미국 특허 2,632,058로 등록되었습니다. 특허는 이 방식을 반사 이진 코드라고 부르며 인접한 표현 진폭이 한 펄스 위치에서 다름을 강조합니다. 관련 단위 거리 수열은 이 특허보다 앞서 존재했으므로, 모든 그런 수열을 그레이가 발명했다고 하기보다는 이 영향력 있는 응용과 명명 계보에 그레이의 공을 돌리는 편이 더 정확합니다.
흔한 함정
- 산술이 된다고 가정하기. 그레이 코드 값을 비트 단위로 더하면 말이 안 되는 결과가 나옵니다. 항상 먼저 이진수로 변환하세요.
- MSB-0 규약 무시하기. 이진수-그레이 코드 공식은 MSB 위에 가상의 0이 있다고 가정합니다. 이를 잊으면 최상위 비트의 부호가 뒤집힙니다.
- 그레이 코드와 시프트 레지스터 루프 섞기. SISO/SIPO 설계처럼 표준 시프트 레지스터는 비트를 옆으로 이동시키며 끝에서 끝까지 단위 거리 성질을 보존하지 않습니다. 경계에서 변환하세요.
- 그레이 코드와 원-핫 혼동하기. 원-핫 인코딩은 한 번에 하나의 비트만 설정되어 다른 의미에서 글리치에 강하지만, 폭이 이 아니라 입니다. 그레이 코드는 더 압축적인 선택입니다.
다음 단계
공개된 SISO, SIPO, PISO, PIPO 가이드는 흔히 쓰는 네 가지 시프트 레지스터 데이터 경로를 비교합니다. 일반 시프트 레지스터를 비동기 FIFO의 대체물로 쓰지 마세요. 관련된 다중 비트 데이터에는 클록 경계를 넘어 일관성을 보존하는 프로토콜이 필요합니다.
그레이 코드를 실제로 보려면 4비트 이진 카운터 템플릿을 불러와 변환기를 만들고 출력 레지스터를 추가한 뒤 연속하는 등록값의 해밍 거리를 확인하세요. 그다음 지연을 인식하는 모델에서 일부러 레지스터를 제거하고 전환 중 동작을 관찰해 보세요.
