Designing Adders in Verilog and SystemVerilog

Digital circuits can perform various operations, including addition. In this post, we'll explore the design of three different adder circuits: the half adder, the full adder, and the carry ripple adder.

Designing a Half Adder in Verilog and SystemVerilog

A half adder is a digital circuit that adds two single-bit binary numbers and outputs their sum and carry. Here's an example of a half adder module:

module HalfAdder (
  input  logic a, b,
  output logic sum, carry
);
  assign sum = a ^ b;
  assign carry = a & b;
endmodule

In this example, we've defined a module called HalfAdder with input variables a and b, and output variables sum and carry. The sum variable is calculated using an XOR gate, while the carry variable is calculated using an AND gate.

Designing a Full Adder in Verilog and SystemVerilog

A full adder is a digital circuit that adds two binary numbers and a carry, and outputs their sum and a carry. Here's an example of a full adder module:

module FullAdder (
  input  logic a, b, cIn,
  output logic sum, cOut
);
  assign sum = a ^ b ^ cIn;
  assign cOut = (a & b) | (a & cIn) | (b & cIn);
endmodule

In this example, we've defined a module called FullAdder with input variables a, b, and cIn, and output variables sum and cOut. The sum variable is calculated using an XOR gate, while the cOut variable is calculated using a combination of AND and OR gates.

Designing a 4-Bit Carry Ripple Adder Using Four Full Adders in Verilog and SystemVerilog

A carry ripple adder is a digital circuit that adds two or more binary numbers by cascading full adders. Here's an example of a 4-bit carry ripple adder module that uses four instances of the FullAdder module:

module FourBitCarryRippleAdder (
  input  logic [3:0] a, b,
  output logic [3:0] sum,
  output logic       cOut
);

  logic c0, c1, c2;

  FullAdder fa0 (.a(a[0]), .b(b[0]), .cIn(1'b0), .sum(sum[0]), .cOut(c0));
  FullAdder fa1 (.a(a[1]), .b(b[1]), .cIn(c0),   .sum(sum[1]), .cOut(c1));
  FullAdder fa2 (.a(a[2]), .b(b[2]), .cIn(c1),   .sum(sum[2]), .cOut(c2));
  FullAdder fa3 (.a(a[3]), .b(b[3]), .cIn(c2),   .sum(sum[3]), .cOut(cOut));

endmodule

In this example, we've defined a module called FourBitCarryRippleAdder with input variables a and b, and output variables sum and cOut. We've also defined three intermediate c variables to hold the carry-out from each full adder. The four full adders are instantiated and connected in a chain, with the carry-out of each full adder being connected to the carry-in of the next full adder, and the carry-out of the final full adder being the output carry.

Designing a Multi-Bit Carry Ripple Adder in Verilog and SystemVerilog

A multi-bit carry ripple adder is a digital circuit that adds two binary numbers of arbitrary width by cascading full adders. Here's an example of a carry ripple adder module that uses a parameter for the width:

module CarryRippleAdder #(
  parameter Width = 8
) (
  input  logic [Width-1:0] a, b,
  output logic [Width-1:0] sum,
  output logic             cOut
);
  logic [Width-1:0] c;

  FullAdder #(.Width(1)) fa [Width-1:0] (
    .a(a),
    .b(b),
    .cIn({1'b0, c}),
    .sum(sum),
    .cOut(c)
  );

  assign cOut = c[Width-1];

endmodule

In this example, we've defined a module called CarryRippleAdder with a parameter Width for the width of the input variables, input variables a and b, and output variables sum and cOut. We use the FullAdder module to create a chain of full adders that calculate the sum and carry-out for each bit. The carry-in for the first full adder is always 0. The carry-out of the final full adder is the output carry. We also define an intermediate variable c to hold the carry-out from each full adder.

By following these examples, you can gain a solid understanding of how to design half adders, full adders, and carry ripple adders in Verilog and SystemVerilog.