목차
그레이 코드 변환 회로
- 개요 1.1. 그레이 코드란? 1.2. 그레이 코드 → 이진 코드 변환 원리 1.3. 이진 코드 → 그레이 코드 변환 원리
- 설계 과제
- Verilog 모듈 구현 3.1. 그레이 코드에서 이진 코드로 변환 3.2. 이진 코드에서 그레이 코드로 변환
- 시뮬레이션 테스트 벤치 설계
- 시뮬레이션 결과 분석
그레이 코드 변환 회로
그레이 코드는 이진 순환 코드의 한 종류로, 인접한 숫자 간의 변화 시 단 하나의 비트만 전환된다는 특징이 있습니다. 이러한 특성으로 인해 이진 인코딩 카운터 조합 회로에서 발생할 수 있는 메타스태일 상태를 방지할 수 있습니다. 그레이 코드는 통신 시스템, 비동기 FIFO, 또는 RAM 주소 계수기 등에서 널리 사용됩니다.
1. 개요
그레이 코드는 1953년 프랭크 그레이(Frank Gray)가 발명한 인코딩 방식으로, 초기에는 통신 분야에서 사용되었습니다. 그레이 코드는 순환 이진 코드 또는 반사 이진 코드라고도 불립니다. 그레이 코드의 가장 큰 특징은 인접한 숫자 간의 변화 시 단 하나의 비트만 전환된다는 점입니다. 이러한 특성 덕분에 이진 인코딩 카운터 조합 회로에서 발생할 수 있는 메타스태일 상태를 방지할 수 있습니다. 그레이 코드는 통신, FIFO, RAM 주소 계수기 등에서 주로 사용됩니다.
그레이 코드는 신뢰성 있는 인코딩 방식으로, 오류를 최소화하는 인코딩 방법 중 하나입니다. 이진 코드는 직접적으로 아날로그 신호로 변환될 수 있지만, 예를 들어 십진수 3에서 4로 변환될 때 모든 비트가 변화하여 디지털 회로에서 큰 스파이크 전류 펄스를 발생시킬 수 있습니다. 반면 그레이 코드는 인접 비트 간 변환 시 단 한 비트만 변화하므로 이러한 단점이 없습니다. 이는 한 상태에서 다음 상태로 전환될 때 발생하는 논리적 혼란을 크게 줄여줍니다.
0부터 15까지의 이진 카운팅 과정은 다음과 같습니다:
위 대응 관계에서 볼 수 있듯이, 숫자가 7에서 8로 변할 때 4비트 이진 수의 모든 비트가 동시에 전환됩니다. 이러한 신호를 비동기 클럭으로 직접 샘플링하면 메타스태일 상태나 데이터 샘플링 오류가 발생할 가능성이 높습니다. 그레이 코드를 사용하면 4비트 이진 수가 동시에 전환되어 발생하는 메타스태일 상태를 방지할 수 있으며, 만약 메타스태일이 발생하더라도 최대 한 비트에서 오류가 발생합니다.
일반적인 디자인에서는 이진 코드를 사용하지만, 그레이 코드를 사용하려면 어떻게 변환해야 할까요? 이는 그레이 코드와 이진 코드 간의 상호 변환 문제와 관련이 있습니다. 먼저 그레이 코드를 이진 코드로 변환하는 방법을 살펴보겠습니다.
1.2. 그레이 코드 → 이진 코드 변환 원리:
그레이 코드의 최상위 비트를 이진 코드의 최상위 비트로 사용하고, 이진 코드의 다음 상위 비트는 이진 코드 상위 비트와 그레이 코드 다음 상위 비트의 XOR 연산을 통해 얻습니다. 나머지 비트들도 이와 유사한 방식으로 생성됩니다.
n비트 이진 코드와 그레이 코드의 각 비트는 다음과 같이 표기하겠습니다:
- n비트 이진 코드: Bn, Bn-1, Bn-2, ..., B2, B1, B0
- n비트 그레이 코드: Gn, Gn-1, Gn-2, ..., G2, G1, G0
- 변환 공식: Bn = Gn
- Bi-1 = Bi ^ Gi-1 (i=0,1,2,...,n-1)
변환 과정은 다음과 같이 나타낼 수 있습니다 (8비트 데이터 예시):
이제 4비트 그레이 코드와 이진 코드 변환 예시를 살펴보겠습니다.
그림에서 볼 수 있듯이, 이진 코드의 최상위 비트와 그레이 코드의 최상위 비트는 모두 1로 동일합니다. 다음 상위 비트(bit2)는 이진 코드 상위 비트와 그레이 코드 다음 상위 비트의 XOR 연산을 통해 0(=1^1)이 됩니다.
그레이 코드를 이진 코드로 변환하는 방법을 소개했으니, 이제 이진 코드를 그레이 코드로 변환하는 방법을 살펴보겠습니다.
1.3. 이진 코드 → 그레이 코드 변환 원리:
이진 코드의 최상위 비트를 그레이 코드의 최상위 비트로 사용하고, 그레이 코드의 다음 상위 비트는 이진 코드 상위 비트와 다음 상위 비트의 XOR 연산을 통해 얻습니다. 나머지 비트들도 이와 유사한 방식으로 생성됩니다.
n비트 이진 코드와 그레이 코드의 각 비트는 다음과 같이 표기하겠습니다:
- n비트 이진 코드: Bn, Bn-1, Bn-2, ..., B2, B1, B0
- n비트 그레이 코드: Gn, Gn-1, Gn-2, ..., G2, G1, G0
- 변환 공식: Gn = Bn
- Gi-1 = Bi ^ Bi-1 (i=0,1,2,...,n-1)
변환 과정은 다음과 같이 나타낼 수 있습니다 (8비트 데이터 예시):
그림에서 쉽게 알 수 있듯이, 이진 코드를 오른쪽으로 1비트 시프트한 후 원본과 XOR 연산을 수행하면 그레이 코드가 됩니다. 가장 오른쪽 비트부터 시작하여 각 비트를 왼쪽 비트와 XOR 연산한 결과를 그레이 코드의 해당 비트 값으로 사용하면 되며, 가장 왼쪽 비트는 그대로 유지됩니다.
2. 설계 과제
Verilog HDL을 사용하여 그레이 코드를 이진 코드로 변환하는 회로와 이진 코드를 그레이 코드로 변환하는 회로를 설계합니다.
3. Verilog 모듈 구현
3.1. 그레이 코드 → 이진 코드 변환
먼저 그레이 코드를 이진 코드로 변환하는 코드를 작성해 보겠습니다. 개요에서 설명한 그레이 코드를 이진 코드로 변환하는 방법을 바탕으로 다음과 같은 코드를 작성할 수 있습니다.
코드 예시:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// 회사:
// 엔지니어:
//
// 생성일: 2023/06/20 17:15:34
// 디자인 이름:
// 모듈 이름: gray_to_binary
// 프로젝트 이름:
// 타겟 디바이스:
// 도구 버전:
// 설명: 그레이 코드를 이진 코드로 변환하는 모듈
//
// 의존성:
//
// 수정 기록:
// 수정 0.01 - 파일 생성
// 추가 설명:
//
//////////////////////////////////////////////////////////////////////////////////
// 설계 과제
// Verilog HDL을 사용하여 그레이 코드를 이진 코드로 변환하는 회로와
// 이진 코드를 그레이 코드로 변환하는 회로를 설계합니다.
// 그레이 코드 → 이진 코드 변환 모듈
module gray_to_binary(
input [WIDTH-1:0] gray_input,
output reg [WIDTH-1:0] binary_output
);
// 매개변수 정의
parameter WIDTH = 4;
//===================================================
// ------------------- 메인 코드 -------------------
//===================================================
always @(*) begin
binary_output[WIDTH-1] = gray_input[WIDTH-1];
binary_output[WIDTH-2] = gray_input[WIDTH-2] ^ binary_output[WIDTH-1];
binary_output[WIDTH-3] = gray_input[WIDTH-3] ^ binary_output[WIDTH-2];
binary_output[WIDTH-4] = gray_input[WIDTH-4] ^ binary_output[WIDTH-3];
end
endmodule
3.2. 이진 코드 → 그레이 코드 변환
이제 이진 코드를 그레이 코드로 변환하는 코드를 작성해 보겠습니다. 개요에서 설명한 이진 코드를 그레이 코드로 변환하는 방법을 바탕으로 다음과 같은 코드를 작성할 수 있습니다.
코드 예시:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// 회사:
// 엔지니어:
//
// 생성일: 2023/06/20 17:17:23
// 디자인 이름:
// 모듈 이름: binary_to_gray
// 프로젝트 이름:
// 타겟 디바이스:
// 도구 버전:
// 설명: 이진 코드를 그레이 코드로 변환하는 모듈
//
// 의존성:
//
// 수정 기록:
// 수정 0.01 - 파일 생성
// 추가 설명:
//
//////////////////////////////////////////////////////////////////////////////////
// 설계 과제
// Verilog HDL을 사용하여 그레이 코드를 이진 코드로 변환하는 회로와
// 이진 코드를 그레이 코드로 변환하는 회로를 설계합니다.
// 이진 코드 → 그레이 코드 변환 모듈
module binary_to_gray(
input [WIDTH-1:0] binary_input,
output reg [WIDTH-1:0] gray_output
);
parameter WIDTH = 4;
//================================================================
// ------------------------- 메인 코드 --------------------------
//================================================================
always @(*) begin
// 가장 왼쪽 비트는 그대로 유지
gray_output[WIDTH-1] = binary_input[WIDTH-1];
// 나머지 비트는 현재 비트와 왼쪽 비트의 XOR 결과
for (int i = WIDTH-2; i >= 0; i = i - 1) begin
gray_output[i] = binary_input[i] ^ binary_input[i+1];
end
end
endmodule
4. 시뮬레이션 테스트 벤치 설계
이제 회로를 테스트하기 위한 테스트 벤치를 작성해 보겠습니다. 이 테스트 벤치는 연속적으로 변하는 이진 수를 입력으로 사용하며, 100ns마다 입력 값을 1씩 증가시킵니다. 시뮬레이션을 통해 이진 코드에서 그레이 코드로 변환되는 파형을 확인할 수 있습니다.
테스트 벤치 코드 예시:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// 회사:
// 엔지니어:
//
// 생성일: 2023/06/20 17:23:23
// 디자인 이름:
// 모듈 이름: gray_conversion_tb
// 프로젝트 이름:
// 타겟 디바이스:
// 도구 버전:
// 설명: 그레이 코드 변환 모듈의 테스트 벤치
//
// 의존성:
//
// 수정 기록:
// 수정 0.01 - 파일 생성
// 추가 설명:
//
//////////////////////////////////////////////////////////////////////////////////
module gray_conversion_tb();
// 테스트 신호 정의
reg [3:0] test_counter;
reg [3:0] binary_input;
wire [3:0] gray_output;
// 테스트 스트림 생성
initial begin
// 초기화
test_counter = 4'd0;
binary_input = 4'd0;
// 0부터 15까지 카운트
for (int i = 0; i < 16; i = i + 1) begin
binary_input = i;
#100; // 100ns 동안 유지
end
// 시뮬레이션 종료
$finish;
end
// 이진 코드 → 그레이 코드 변환 모듈 인스턴스화
binary_to_gray dut (
.binary_input(binary_input),
.gray_output(gray_output)
);
// 모니터링
initial begin
$monitor("Time = %0t, Binary = %b, Gray = %b",
$time, binary_input, gray_output);
end
endmodule
5. 시뮬레이션 결과 분석
테스트 프로그램을 Modelsim 또는 다른 시뮬레이션 도구(예: Xilinx Vivado)에서 실행한 결과 파형은 다음과 같습니다. 이진 숫자가 순차적으로 증가할 때마다 여러 비트가 전환되는 반면, 그레이 코드는 항상 단 하나의 비트만 전환되는 것을 볼 수 있습니다. 이러한 특성은 이진 숫자가 순차적으로 증가할 때만 나타나며, 이진 숫자의 변화가 무작위적인 경우 그레이 코드에서도 여러 비트가 전환될 수 있습니다. FIFO 디자인에서 읽기/쓰기 주소는 연속적으로 변하므로, 그레이 코드는 FIFO 주소 처리에 매우 적합합니다.