CMOS Logic Gates

We left the last lesson with two switches and one rule: the NMOS passes a clean 0, the PMOS passes a clean 1, and neither should do the other's job. CMOS — Complementary Metal-Oxide-Semiconductor — is the beautifully simple idea that falls out of obeying that rule: build every logic gate from two switch networks, one made of PMOS that can only pull the output up to V_{DD}, and one made of NMOS that can only pull it down to ground. Arrange them so that in every input state exactly one network conducts, and you get a gate that always drives a strong value and — the killer feature — draws essentially no current while it sits still.

Nearly every digital chip built since the 1980s is static CMOS. Understanding these four transistors in an inverter is understanding the atom of the entire industry.

Two networks, pulling opposite ways

Every static CMOS gate has the same skeleton, drawn between the two supply rails:

The two networks are complementary: for any input pattern, one and only one is conducting. If both conducted at once you would short V_{DD} to ground (a crowbar current, and smoke); if neither did, the output would float. The correctness and the low power of CMOS both come from that "exactly one" guarantee.

The inverter: the smallest complete gate

Wire a single PMOS as the pull-up and a single NMOS as the pull-down, tie both gates to the same input A, and join both drains at the output Y. That is the CMOS inverter — two transistors, and the seed of everything.

Trace it. When A = 0, the PMOS (which turns on for a low gate) conducts and the NMOS is off, so Y is yanked up to a strong 1. When A = 1, the switches flip: NMOS on, PMOS off, and Y is dragged down to a strong 0. Output is always the opposite of the input, always full-rail, and in neither stable state is there a path from V_{DD} to ground. That is why it barely sips power.

Series means AND, parallel means OR — and the two networks are duals

To build bigger gates, translate boolean conditions into switch topology. In the pull-down network:

The pull-up network is always the dual: wherever the PDN puts transistors in series, the PUN puts them in parallel, and vice versa. This series-parallel duality guarantees the "exactly one conducts" property automatically — you design one network and the other is forced.

NAND and NOR are the "natural" gates

Build a two-input NAND: it must output 0 only when both inputs are 1, so the pull-down needs both NMOS conducting — two NMOS in series. The dual pull-up is two PMOS in parallel. Four transistors, and it computes Y = \overline{A \cdot B}. NOR is the mirror: two NMOS in parallel below, two PMOS in series above, giving Y = \overline{A + B}.

GatePull-down (NMOS)Pull-up (PMOS)Transistors
Inverter (NOT)112
NAND22 in series2 in parallel4
NOR22 in parallel2 in series4
AND2NAND2 then an inverter6
OR2NOR2 then an inverter6

Notice the pattern: CMOS gates are inherently inverting. A single network of switches naturally computes NAND or NOR, because pulling the output down (to 0) on an AND-of-inputs is an inverting operation. A plain AND or OR is not natural — you must bolt an inverter onto a NAND/NOR, paying two extra transistors and one extra gate delay. This is why chip libraries are dominated by NAND, NOR and inverters, and why NAND is a universal gate: give a logic synthesiser a pile of NANDs and it can build anything.

Simulate the gates from their switch networks

We can compute each gate's truth table directly from "which network conducts," never hand-writing the logic — proof that the topology is the function.

// Evaluate a static CMOS gate from its pull-down network alone (pull-up is the dual). // The PDN pulls the output to 0; otherwise the PUN pulls it to 1. type Bit = 0 | 1; // NAND: PDN = two NMOS in SERIES -> conducts (output 0) only when BOTH inputs are 1. function nand(a: Bit, b: Bit): Bit { const pdnConducts = a === 1 && b === 1; // series => AND return pdnConducts ? 0 : 1; } // NOR: PDN = two NMOS in PARALLEL -> conducts when EITHER input is 1. function nor(a: Bit, b: Bit): Bit { const pdnConducts = a === 1 || b === 1; // parallel => OR return pdnConducts ? 0 : 1; } const bits: Bit[] = [0, 1]; console.log("A B | NAND NOR"); for (const a of bits) for (const b of bits) { console.log(`${a} ${b} | ${nand(a, b)} ${nor(a, b)}`); } // AND is NAND then an inverter -> the "unnatural", 6-transistor gate. const and = (a: Bit, b: Bit): Bit => (nand(a, b) === 1 ? 0 : 1); console.log("AND(1,1) = " + and(1, 1) + " (built from NAND + inverter)");

In a stable state one network is off, so no DC flows — that is the near-zero static power. But during the brief moment an input crosses the threshold, there is a sliver of time when both networks conduct a little at once, and a small short-circuit current spikes from V_{DD} to ground. On top of that, every switch must charge or discharge the load capacitance, costing C V_{DD}^2 of energy per transition. Sum those over a billion transistors switching a billion times a second and you get dynamic power, P \approx \alpha C V_{DD}^2 f — the term that actually heats your laptop. CMOS is cheap at rest and expensive in motion, which is exactly why clock gating and lowering V_{DD} are such powerful knobs.

A classic beginner circuit puts NMOS in the pull-up "to save PMOS." It does not work. An NMOS in the pull-up would only pass a weak 1 — the output would never reach the full rail, noise margins collapse, and the next gate might misread it. The complementary structure is not a stylistic choice: PMOS must pull up because only it passes a strong 1, and NMOS must pull down because only it passes a strong 0. The names "complementary MOS" describe the one arrangement that gives full-rail outputs.

From gates to everything

You now have the full bridge from physics to logic: switches from silicon, gates from switches. From here the abstraction only ever goes up. Wire NANDs into an adder and an ALU to compute, and cross-couple a pair of inverters to build the latches and flip-flops that remember. Every one of the billions of gates on a modern die is this same four-transistor idea, printed over and over.