53. Full Adder

Build a 1-bit full adder using two half adders and an OR gate.

Requirements

  • Module: full_adder_struct
  • Inputs: a, b, cin
  • Outputs: sum, cout
  • First half adder computes a ⊕ b.
  • Second half adder computes (a⊕b) ⊕ cin.
  • OR gate merges the carries.

Behavior

  • Inputs: a, b, cin
  • Outputs: sum, cout
  • Truth table:
abcinsumcout
00000
00110
01010
01101
10010
10101
11001
11111


 

Testbench Code

`timescale 1ns/1ps

module tb_full_adder_struct;
    // Inputs
    reg a, b, cin;

    // DUT outputs
    wire sum, cout;

    // Expected
    reg expected_sum, expected_cout;

    // Mismatch flag
    reg mismatch;
    wire mismatch_w = ((sum !== expected_sum) || (cout !== expected_cout));

    // Counters
    integer TOTAL_TEST_CASES        = 0;
    integer TOTAL_PASSED_TEST_CASES = 0;
    integer TOTAL_FAILED_TEST_CASES = 0;

    // VCD limit
    integer VCD_MAX_CASES = 16;

    // DUT
    full_adder_struct dut(.a(a), .b(b), .cin(cin), .sum(sum), .cout(cout));

    // VCD dump
    initial begin
        $dumpfile("tb_full_adder_struct.vcd");
        $dumpvars(0,
            tb_full_adder_struct.a,
            tb_full_adder_struct.b,
            tb_full_adder_struct.cin,
            tb_full_adder_struct.sum,
            tb_full_adder_struct.cout,
            tb_full_adder_struct.expected_sum,
            tb_full_adder_struct.expected_cout,
            tb_full_adder_struct.mismatch
        );
        $dumpon;
    end

    // Display header
    initial begin
        {a,b,cin} = 3'b000; expected_sum = 0; expected_cout = 0; mismatch = 0;
        $display(" a b cin | sum cout | exp_sum exp_cout | mismatch");
        $display("---------------------------------------------------");
    end

    // Apply + check
    task apply_and_check;
        input ta, tb, tcin;
        begin
            a = ta; b = tb; cin = tcin;

            // expected first
            expected_sum  = ta ^ tb ^ tcin;
            expected_cout = (ta & tb) | (tb & tcin) | (ta & tcin);

            #1;
            mismatch = mismatch_w;

            TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
            if (!mismatch) TOTAL_PASSED_TEST_CASES++;
            else           TOTAL_FAILED_TEST_CASES++;

            $display(" %b %b  %b  |  %b    %b  |    %b        %b     |    %0d",
                     a, b, cin, sum, cout, expected_sum, expected_cout, mismatch);

            if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
        end
    endtask

    integer i;
    initial begin
        // All 8 input combinations
        for (i = 0; i < 8; i = i + 1)
            apply_and_check(i[2], i[1], i[0]);

        // Summary
        $display("---------------------------------------------------");
        $display("TOTAL_TEST_CASES=%0d", TOTAL_TEST_CASES);
        $display("TOTAL_PASSED_TEST_CASES=%0d", TOTAL_PASSED_TEST_CASES);
        $display("TOTAL_FAILED_TEST_CASES=%0d", TOTAL_FAILED_TEST_CASES);
        $display("ALL_TEST_CASES_PASSED=%s", (TOTAL_FAILED_TEST_CASES==0) ? "true" : "false");

        #2 $finish;
    end
endmodule