4-bit Adder and Subtractor

Seungyun Lee·2025년 10월 28일

14–5 = 1110–0101

Change 5(0101) by using 2’s Complement

0101-> 1010+1 -> 1011

14–5=1110+1011, carry=1

12–7 = 1100–0111 = 1100+1001= 0101, carry =1

Change B by adding NOT, and put Carry 1 to make 2’s complement

When CTR is 1, XOR gate make B invert for 2’s complement. (act as Subtractor)
When CTR is 0, this circuit act as Adder

when A<B , result is minus, like 10–12=-2

put the NOT gate and AND gate

Full Adder

Sum = A ⊕ B ⊕ Cin
Cout = (A & B) | (A & Cin) | (B & Cin)

Verilog Code

module full_adder(
  input a, b, cin,
  output sum, cout);
  assign sum = a^b^cin;
  assign cout = (a & b) | (b & cin) | (a & cin);
endmodule

module ripple_carry_adder_subtractor ( 
  input [3:0] A, B, 
  input CTRL,
  output [3:0] S, Cout);
  
  wire [3:0] Bc; // Bc = B complement
  
  assign Bc = B ^ {4{CTRL}}; 
    
  full_adder fa0(A[0], Bc[0], CTRL, S[0], Cout[0]);
  full_adder fa1(A[1], Bc[1], Cout[0], S[1], Cout[1]);
  full_adder fa2(A[2], Bc[2], Cout[1], S[2], Cout[2]);
  full_adder fa3(A[3], Bc[3], Cout[2], S[3], Cout[3]);
  
endmodule
Bc = B ^ {4{CTRL}}; 이거를 풀어서 쓰면 아래와 같다
assign Bc[0] = B[0] ^ CTRL;
assign Bc[1] = B[1] ^ CTRL;
assign Bc[2] = B[2] ^ CTRL;
assign Bc[3] = B[3] ^ CTRL;

이런 식으로 캐리가 Ripple(흘러가는) 구조가 되기 때문에
→ 이름이 “Ripple Carry Adder” 입니다.

내부 동작 구조 (각 자리별)

자리(g) full_adder 입력 설명
g=1 A[1], Bc[1], Cout[0] 이전 자리의 캐리(Cout[0])를 입력으로 받음
g=2 A[2], Bc[2], Cout[1] Cout[1]을 입력으로 받음
g=3 A[3], Bc[3], Cout[2] Cout[2]을 입력으로 받음

Bc[g] = B[g] ^ CTRL; 의 역할

이건 각 비트마다 B를 반전시킬지 말지를 정하는 코드
따라서 Bc[g]는 덧셈일 때는 그냥 B,뺄셈일 때는 반전된 B 값
그리고 첫 자리의 cin이 1이므로 결과적으로 A + (~B) + 1이 되어 A - B 가 됨.

             ┌───────────────┐
 A[0] ───►   │               │
 B[0] ─►XOR──► full_adder fa0│──► Cout[0]
 CTRL ───────► (Cin = CTRL)  │
             └───────────────┘
                     │
                     ▼
             ┌───────────────┐
 A[1] ───►   │ full_adder fa1│──► Cout[1]
 B[1] ─►XOR──► (Cin = Cout[0])│
             └───────────────┘
                     │
                     ▼
             ┌───────────────┐
 A[2] ───►   │ full_adder fa2│──► Cout[2]
 B[2] ─►XOR──► (Cin = Cout[1])│
             └───────────────┘
                     │
                     ▼
             ┌───────────────┐
 A[3] ───►   │ full_adder fa3│──► Cout[3]
 B[3] ─►XOR──► (Cin = Cout[2])│
             └───────────────┘

Testbench

module RCAS_TB;
  wire [3:0] S, Cout;
  reg [3:0] A, B;
  reg ctrl;
  
  //DUT (Device Under Test) 연결
  ripple_carry_adder_subtractor rcas(A, B, ctrl, S, Cout);
  
  initial begin //initial 블록은 시뮬레이션이 시작될 때 한 번만 실행됨.
    $monitor("CTRL=%b: A = %b, B = %b --> S = %b, Cout[3] = %b", ctrl, A, B, S, Cout[3]);
    ctrl = 0;
    A = 1; B = 0;
    #3 A = 2; B = 4;
    #3 A = 4'hb; B = 4'h6; //16진수 11, 16진수 6
    #3 A = 5; B = 3;
    ctrl = 1;
    A = 1; B = 0;
    #3 A = 2; B = 4;
    #3 A = 4'hb; B = 4'h6;
    #3 A = 5; B = 3;
    #3 $finish;
  end
  
  initial begin
    $dumpfile("waves.vcd");
    $dumpvars;
  end
endmodule

$monitor — 콘솔에 결과 출력

$dumpfile, $dumpvars — 파형 파일 저장
시뮬레이터가 파형(waveform) 파일을 저장하게 하는 명령
"waves.vcd"라는 파일에 시간에 따른 신호 변화를 저장

ALL ABOUT ELECTRONICS 4-bit Adder and Subtractor Circuit Explained https://youtu.be/J7gPUP0aRug?si=3Kagk_--fqSdvPkT
VLSI Verify, https://vlsiverify.com/verilog/verilog-codes/4-bit-adder-subtractor/

profile
RTL, FPGA Engineer

0개의 댓글