본문 바로가기
verilog/실습

[Verilog] 조합회로(Combinational logic) : 인코더(Encoder)와 디코더(Decoder)

by 씐 2025. 3. 4.
728x90

인코더와 디코더 차이

비교 항목 인코더 (Encoder) 디코더 (Decoder)
입력(Input) 여러 개의 신호 중 하나만 활성화 압축된(코드화된) 데이터를 입력
출력(Output) 코드화된 신호 (예: 2진수) 원래 의미 있는 정보 (예: BCD, 7세그먼트 신호)
예시 10진 → 2진 (Decimal to Binary) 변환기 2진 → 10진 (Binary to BCD) 변환기
사용처 키패드 입력, 우선순위 인코딩 7세그먼트 디스플레이, 주소 해석

 

BCD(Binary-Coded Demical)이란?

10진수 2진수(8비트) BCD 코드 (4비트 × 3)
156 10011100 0001 0101 0110
47 00101111 0000 0100 0111
255 11111111 0010 0101 0101
  • 2진수(Binary)로 10진수(Demical)를 표현하는 방식
  • 10진수 자리(0~9)를 4비트 2진수로 변환하여 표현하는 방식
  • 10진수 각 자리(백, 십, 일의 자리)를 독립적인 4비트 2진수로 표현
  • BCD의 장점 : 10진수와 직접적인 호환이 가능

 

Double Dabble 알고리즘

  • 2진수를 BCD로 변환하는 방법
  • shift(왼쪽 이동) + Adjust(5 이상이면 +3 보정)을 반복적으로 수행
  • 방법
    • BCD 자리 확보
      • 변환할 2진수(N비트)와 그보다 긴 BCD 변환을 위한 공간(Shifting Register)을 만든다.
      • 예를 들어, 8비트 이진수를 변환할 때, 최소 12비트 공간(백, 십, 일의 자리) 필요.
    • 왼쪽으로 shift
      • 입력된 2진수를 하나씩 왼쪽으로 이동
    • 보정(Adjust) 과정
      • Shift하기 전에, BCD 자리(백, 십, 일의 자리)가 5 이상이면 +3 추가
      • 이유: BCD는 10진수 표현이므로, 5 이상일 경우 다음 Shift에서 올바른 변환이 되도록 조정
    • N번 반복(입력 비트 수만큼)
      • 위 과정을 2진수 비트 수만큼 반복하면 최종적으로 BCD 변환이 완료됨.
  • 예시
단계 백(4비트) 십(4비트) 일(4비트) 2진수
초기값 0000 0000 0000 10011100
1 Shift 0000 0000 0001 00111000
2 Shift 0000 0000 0010 01110000
3 Shift 0000 0000 0100 11100000
4 Shift 0000 0000 1001 11000000
+3 적용 0000 0000 1100 11000000
5 Shift 0000 0001 1001 10000000
+3 적용 0000 0001 1100 10000000
6 Shift 0000 0011 1001 00000000
+3 적용 000 0011 1100 00000000
7 Shift 0000 0111 1000 00000000
+3 적용 0000 1010 1011 00000000
8 Shift 0001(1) 0101(5) 0110(6) 00000000

 

 

verilog 코드

// 8비트 Binary to BCD 변환기 설계

module binary_to_bcd (binary, bcd_100, bcd_10,  bcd_1);
  
  input  [7:0] binary;
  output reg [3:0] bcd_100;
  output reg [3:0] bcd_10;
  output reg [3:0] bcd_1;
  
  integer i;
  reg [11:0] shift_reg; // BCD 변환을 위한 12비트 레지스터
  
 always @(binary) begin
  shift_reg = 12'd0; // 초기화
  
  // 비트별로 처리
  for(i = 7; i >= 0; i = i - 1) begin
    // 5 이상이면 +3 보정 적용
    if (shift_reg[11:8] >= 5)
      shift_reg[11:8] = shift_reg[11:8] + 3;
    
    if (shift_reg[7:4] >= 5)
      shift_reg[7:4] = shift_reg[7:4] + 3;
    
    if (shift_reg[3:0] >= 5)
      shift_reg[3:0] = shift_reg[3:0] + 3;
    
    shift_reg = shift_reg << 1;
    shift_reg[0] = binary[i]; // 현재 처리 중인 비트 삽입
    
  end
  
  // BCD 값 할당
  bcd_100 = shift_reg[11:8];
  bcd_10 = shift_reg[7:4];
  bcd_1 = shift_reg[3:0];
  
end
  
endmodule

 

테스트벤치

module tb_binary_to_bcd;
  
  reg [7:0] binary;
  wire [3:0] hundreds, tens, ones;
  
  binary_to_bcd UUT(.binary(binary), .bcd_100(hundreds), .bcd_10(tens), .bcd_1(ones));
  
  initial begin
    
    $dumpfile("dump.vcd");
    $dumpvars(0);
    
    binary = 8'd156; #100;
    binary = 8'd47; #100;
    binary = 8'd255; #100;
    binary = 8'd99; #100;
    binary = 8'd123; #100;
    
  end
  
endmodule

 

Waveform