Personal Project/Binary Adder 구현

04 4-Bit Adder with Carry-Lookahead 구현

Orangetasteboy 2023. 6. 21. 13:49

  • Design a 4-bit adder with carry-lookahead and verify the design with simulation.

[4bit_adder_with_CLA.v]

// 4-Bit Adder with Carry-Lookahead 정의
module fbit_adder_with_CLA(Sum, C_out, A, B, C_in);
  
  // 포트 선언
  input [3:0] A, B; // 0~3비트끼지 사용 = 0~15까지 사용
  input C_in;
  output [3:0] Sum; // 0~3비트끼지 사용 = 0~15까지 사용
  output C_out;

  // Carry 포트 선언
  wire C1, C2, C3, C4;

  // Propagation 포트와 Genertation 포트 선언
  wire P0, P1, P2, P3, G0, G1, G2, G3;

  // Propagation에 XOR 연산 입력
  assign P0 = A[0]^B[0];
  assign P1 = A[1]^B[1];
  assign P2 = A[2]^B[2];
  assign P3 = A[3]^B[3];
  
  // Generation에 AND 연산 입력
  assign G0 = A[0]&B[0];
  assign G1 = A[1]&B[1];
  assign G2 = A[2]&B[2];
  assign G3 = A[3]&B[3];

  /* Carry-Lookahead Equation 연산 입력
     G = Carry Out이 발생하는 경우
     P = Carry In이 Carry Out으로 전파되는 경우 */
  assign C1 = G0|(P0&C_in);
  assign C2 = G1|(P1&G0)|(P1&P0&C_in);
  assign C3 = G2|(P2&G1)|(P2&P1&G0)|(P2&P1&P0&C_in);
  assign C4 = G3|(P3&G2)|(P3&P2&G1)|(P3&P2&P1&G0)|(P3&P2&P1&P0&C_in);

  assign Sum[0] = P0^C_out; // 첫 번째 모듈의 결과값
  assign Sum[1] = P1^C1; // 두 번째 모듈의 결과값
  assign Sum[2] = P2^C2; // 세 번째 모듈의 결과값
  assign Sum[3] = P3^C3; // 네 번째 모듈의 결과값

  // Adder의 최종 연산 결과값
  assign C_out = C4;
  
endmodule

 

[tb_4bit_adder_with_CLA.v]

// 시뮬레이션을 위한 testbench
module tb_fbit_adder_with_CLA;
  // input을 reg, output을 wire로 선언
  reg [3:0] A, B; // 0~3비트끼지 사용 = 0~15까지 사용
  reg C_in;
  wire [3:0] sum; // 0~3비트끼지 사용 = 0~15까지 사용
  wire C_out;

  //full_adder 모듈 호출
  fbit_adder_with_CLA u_fbit_adder_with_CLA(sum, C_out, A, B, C_in);

  /* 시뮬레이션 결과 확인을 위해 모니터로 출력
     $monitor는 신호의 값이 변할 때마다 출력 */
  initial begin
     $monitor($time, "A= %b, B= %b, C_in= %b, --- C_out= %b, sum = %b\n", A, B, C_in, C_out, sum);
    end

  initial begin
    // A, B는 4비트 Decimal, C_in은 1비트 Binary로 초기값 설정
    A = 4'd0; B = 4'd0; C_in = 1'b0;
  
    /* 5만큼의 delay를 주면서 입력값 입력
       몇 가지 경우의 입력값을 입력 */
    #5 A = 4'd3; B = 4'd2; C_in=1'b0; // 3+2와 Carry가 0인 경우
    #5 A = 4'd3; B = 4'd2; C_in=1'b1; // 3+2와 Carry가 1인 경우
    #5 A = 4'd7; B = 4'd1; C_in=1'b0; // 7+1과 Carry가 0인 경우
    #5 A = 4'd7; B = 4'd1; C_in=1'b1; // 7+1과 Carry가 1인 경우
    #5 A = 4'd10; B = 4'd3; C_in=1'b0; // 10+3과 Carry가 0인 경우
    #5 A = 4'd10; B = 4'd3; C_in=1'b1; // 10+3과 Carry가 1인 경우
    #5 A = 4'd15; B = 4'd1; C_in=1'b0; // 15+1과 Carry가 0인 경우
    #5 A = 4'd15; B = 4'd1; C_in=1'b1; // 15+1과 Carry가 1인 경우
  end

endmodule

 

Parallel Adder Composed of Four Full Adders 프로젝트에서와 마찬가지로,
3+2와 Carry가 0인 경우, 3+2와 Carry가 1인 경우,
7+1과 Carry가 0인 경우, 7+1과 Carry가 1인 경우,
10+3과 Carry가 0인 경우, 10+3과 Carry가 1인 경우,
15+1과 Carry가 0인 경우, 15+4과 Carry가 1인 경우

총 8가지 경우의 수를 입력값으로 주었다.

 

3+2, 7+1, 10+3을 연산한 6가지 경우는 예상 연산값과 동일한 결과값이 출력되는 것을 확인할 수 있다.
15+1을 연산한 두 경우 모두 오버플로우가 일어나는 것을 확인할 수 있다.

 

Parallel Adder Composed of Four Full Adders의 Delay를 해결하기 위한 방법이 4-Bit Adder with Carry-Lookahead이다.  출력 결과값은 같으나, Delay 측면에서 큰 차이가 있다.

Parallel Adder Composed of Four Full Adders는 Carry 연산을 위해 이전 모듈의 결과값을 기다리는 과정에서 Delay가
발생한다.

하지만 4-Bit Adder with Carry-Lookahead에서는 이전 모듈의 결과값 을 기다리지 않고 Carry를 미리 예측해서 연산하므로 Delay가 상대적으로 감소한 다. 이를 위해 Propagation과 Generation 출력을 만들어주어 Carry를 미리 예측하는 연산을 진행한다.

하지만 Gate의 fan-in이 불가피하게 늘어나기 때문에 Cost의 측면에서는 손해를 보게 된다.