Half Adder using NAND Primitive

Solving Approach

How do you plan to solve it?

 

 

Code

// 1-bit Half Adder using only NAND gates
module ha_nand_only (
  input  wire a, 
  input  wire b, 
  output wire sum, 
  output wire cout
);

  wire nand1, nand2, nand3, nand4;

  // Step 1: Generate intermediate NAND signals
  nand (nand1, a, b);         // nand1 = ~(a & b)
  nand (nand2, a, nand1);     // nand2 = ~(a & nand1)
  nand (nand3, b, nand1);     // nand3 = ~(b & nand1)
  nand (sum, nand2, nand3);   // sum = ~(nand2 & nand3) = a ⊕ b
  nand (cout, nand1, nand1);  // cout = ~(~(a & b)) = a & b

endmodule

 

Upvote
Downvote

Testbench Code

`timescale 1ns/1ps
module tb_ha_nand_only;
  reg  a, b;
  wire sum, cout;

  wire expected_sum, expected_cout;
  wire mismatch;

  ha_nand_only dut(.a(a), .b(b), .sum(sum), .cout(cout));

  assign expected_sum  = a ^ b;
  assign expected_cout = a & b;

  assign mismatch = (sum !== expected_sum) | (cout !== expected_cout);

  initial begin
    $dumpfile("tb_ha_nand_only.vcd");
    $dumpvars(0,
      a, b,
      sum, cout,
      expected_sum, expected_cout,
      mismatch
    );
  end

  integer TOTAL_TEST_CASES, TOTAL_PASSED_TEST_CASES, TOTAL_FAILED_TEST_CASES;
  integer ia, ib;

  initial begin
    TOTAL_TEST_CASES = 0; TOTAL_PASSED_TEST_CASES = 0; TOTAL_FAILED_TEST_CASES = 0;

    for (ia = 0; ia < 2; ia = ia + 1) begin
      for (ib = 0; ib < 2; ib = ib + 1) begin
        a = ia[0]; b = ib[0]; #1;
        $display("CASE=a%0d_b%0d : sum=%0b expected_sum=%0b  cout=%0b expected_cout=%0b  %s",
                 a, b, sum, expected_sum, cout, expected_cout, mismatch ? "MISMATCH" : "OK");
        TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
        if (!mismatch) TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
        else begin
          TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
          $display("  FAILED INPUTS: a=%0b b=%0b", a, b);
        end
        #4;
      end
    end

    $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");
    $finish;
  end
endmodule