Combinational Circuits

Combinational circuits produce outputs that depend only on current inputs. Learn the design procedure, half and full adders, ripple-carry and carry-lookahead adders, subtractors with two's complement, magnitude comparators, parity generators, and timing (critical path, glitches).

Arithmetic units, comparators, code converters and decision logic are all combinational — no memory, just gates. The ALU inside every processor is a large combinational circuit.

An analogy

A combinational circuit is like a calculator that only shows the answer to the numbers currently typed — it remembers nothing about previous calculations.

Design procedure

State the problem → define inputs/outputs → write the truth table → simplify (K-map/algebra) → draw the circuit → verify by simulation.

Adders and subtractors

Chaining full adders gives a ripple-carry adder — simple but slow (carry ripples through every bit). Subtraction uses two's complement: invert B and set C_in = 1. Overflow for signed numbers occurs when the carry into and out of the MSB differ.

Comparators and parity

Magnitude comparators produce A > B, A = B, A < B by scanning from the MSB. Parity generators (XOR trees) add a bit to detect single-bit errors in memory and communication.

Fast arithmetic and timing

Carry-lookahead, carry-select and prefix adders (Kogge–Stone) reduce delay to O(log n). The critical path sets maximum clock frequency; unequal path delays cause glitches, which is why outputs are registered.

Formulas

Worked example: Binary addition

Given: A = 1011 (11), B = 0110 (6)

Find: Sum.

Answer: 10001₂ = 17

Worked example: Ripple delay

Given: 32-bit ripple adder, carry delay 0.2 ns per bit

Find: Worst-case delay.

Answer: 6.4 ns

4-bit adder in Verilog

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

module adder4 (input [3:0] a, b, input cin, output [3:0] s, output cout);
  wire c1, c2, c3;
  full_adder fa0 (a[0], b[0], cin, s[0], c1);
  full_adder fa1 (a[1], b[1], c1,  s[1], c2);
  full_adder fa2 (a[2], b[2], c2,  s[2], c3);
  full_adder fa3 (a[3], b[3], c3,  s[3], cout);
endmodule

// Behavioural equivalent: assign {cout, s} = a + b + cin;

Structural code wires four full adders into a ripple-carry adder; the behavioural one-liner lets synthesis choose a faster architecture.

Common mistakes

Applications

Key takeaways

Going further