거북이처럼 천천히

Verilog RTL 설계 (6월 12일 - 2) - Half adder 본문

Verilog/Verilog RTL 설계

Verilog RTL 설계 (6월 12일 - 2) - Half adder

유로 청년 2024. 6. 12. 22:38

서론 

 

Verilog RTL 설계 (6월 12일 - 1) 에서 살펴본 Module의 구조 및 사용법을 기반으로 AND Gate와 XOR Gate의 Module를 구현한 뒤, 이를 사용하여 Half adder를 구현해보도록 하겠다.

 

 

본론

 

Half adder 의 Truth table와 논리 회로 구성은 다음과 같이 구성된다.

 

Half adder의 진리표와 논리 회로

 

  • 해당 내용에서 중요한 부분은 Half adder의 진리표도 중요하지만, Half adder는 XOR gate와 AND gate로 각각 구성된다는 점이 핵심 포인트이다.
  • 따라서 이번 Half adder 를 구현하기 위해서는 XOR gate의 Module과 AND gate의 Module이 필요하다는 것이다.
    (물론 XOR, AND Gate는 기본적으로 library로 제공하지만, Veilog의 실력을 향상을 위해 직접 구현하자.)

 

 

Module of AND Gate.

- AND 게이트의 모듈에 대해서 설계하면 다음과 같이 설계할 수 있다.

module and_gate (
    // Input variable a, b 
    // Output variable q
    input a, b,
    output reg q);
    
    // sensitive variable of always = a, b
    always @(a, b) begin
        case({a, b})
            2'b00 : q = 0;
            2'b01 : q = 0;
            2'b10 : q = 0;
            2'b11 : q = 1;
        endcase
    end
    
endmodule
  • 모듈의 입력 값으로 a, b를 받으며, 출력 값으로 q를 내보낸다.
    다만, 출력 변수 q인 경우에는 always 블록내에서 대입 연산자의 l-value로 활용되기 때문에 출력 변수 q의 자료형을 wire 자료형에서 reg 자료형으로 형변환을 해줘야 한다.
  • always 블록의 감도 변수는 a, b가 되겠으며, AND Gate의 Truth table를 생각하면서 변수 a, b의 값에 따라 and_gate 모듈의 출력 변수 q값을 설정하면 된다. 

 

Module of XOR Gate.

- XOR 게이트의 모듈에 대해서 설계를 한다면 다음과 같이 설계할 수 있다.

// Module about XOR Gate
module xor_gate (
    input a, b,
    output reg q );
    
    // sensitive variable of always block
    always @(a, b) begin 
         case({a, b}) 
             2'b00 : q = 0;
             2'b01 : q = 1;
             2'b10 : q = 1;
             2'b11 : q = 0;
           endcase
     end
    
endmodule
  • and_gate 모듈과 동일하게 입력 값으로 a, b를 받고, 출력 값으로 q를 받는다.
  • 또한 출력 변수 q는 always 블록 내에서 대입 연산자의 l-value로 활용 되기 때문에 wire 자료형이 아닌 reg 자료형으로 형 변환을 해 줄 필요가 있다.

 

Module of Half adder

- Half adder의 논리 회로를 보게 되면 두 가지 출력 값을 갖는데, carry와 sum이라는 변수를 갖는다.

- carry는 입력 값을 합한 결과 자리 올림이 발생하면 1을 출력하며, 두 입력의 AND 연산을 통해 구할 수 있다.

- sum는  입력 값을 합한 결과를 저장하며, 두 입력의 XOR 연산을 통해 구할 수 있다.

- 이러한 내용을 기억하고, 코드로 작성하면 다음과 같이 작성할 수 있다.

 

// Module about Half-adder
module half_adder (
    input a, b,
    output s, c);
    
    // Module('and_gate')의 instance 명으로 carry 설정.
    // Java에서 Class와 instance 관계와 유사
    // Module의 맴버 a, b, c에 값을 대입
    and_gate carry (.a(a), .b(b), .q(c));
    
    // Module('xor_gate')의 instance 명으로 sum 설정.
    xor_gate sum (.a(a), .b(b), .q(s));
    
endmodule
  • half_adder 모듈은 두 개의 입력과 두 개의 출력을 갖는다.
    ▶ 입력 : a, b
    ▶ 출력 : s (sum), c (carry)
  • Q) and_gate carry 는 무엇을 의미하는가?
    A) 이를 이해하기 쉽게 하기 위해서는 Java의 class와 instance 관계로 생각하면 쉽다.
         Module은 Java에서 class와 유사한 개념으로 논리회로를 구성하는 소자이며,
         Instance는 Java와 동일하게 Module에 이름을 붙어 독립적으로 사용하는 것과 유사하다.
  • Q) 그럼 값을 어떻게 대입하는가?
    A) 이 또한 자바에서 Class 맴버에 값을 대입하는 방법과 유사하다.
         .[Module의 변수 명] ([Caller 측에서 대입하고자 하는 변수])   
          →
    (적절한 표현인지 잘 모르겠지만, 난 이렇게 이해하니 조금 편안했다.)

 

 

 

Module of Half adder의 출력 

아래 출력을 통해 Half adder의 Truth table처럼 출력되었음을 확인했다.

Half adder의 출력


     

 

 

Module of Half adder의 또 다른 구현

 

앞에서도 말했지만, AND, XOR Gate는 기본적으로 library로 제공하기 때문에 library를 사용해서 구현하면 다음과 같다.

모듈의 출력  변수 s, c는 대입 연산자의 l-value로서 활용하지 않기 때문에 wire 변수를 reg 변수로 형변환 할 필요 없다,

module half_adder (
    input a, b,
    output s, c); 
    
    and(c, a, b);
    xor(s, a, b);
    
endmodule

Library AND, XOR Gate를 사용해도 동일한 결과를 얻는다.