Open-Drain Output Signals Explained
Open-drain is one of those concepts that comes up in interviews, in I²C debug sessions, and on every datasheet pin definition — and is rarely explained in a way that connects the device-physics view, the system-design view, and the HDL view all at once. This post does that, then walks through pull-up sizing, the I²C waveform, and the gotchas you'll meet on real boards.
What an open-drain output actually is
An open-drain (or, in BJT-land, open-collector) output is a transistor that can do exactly two things: actively pull the line LOW, or release it. It cannot drive HIGH. The HIGH state, when no one is pulling LOW, comes from a passive pull-up resistor connected between the line and the supply rail.
flowchart LR VCC((VCC)) ---|R_pu| BUS[Bus line] BUS --- N1[NMOS open-drain
Driver A] BUS --- N2[NMOS open-drain
Driver B] BUS --- N3[NMOS open-drain
Driver C] N1 --- GND((GND)) N2 --- GND N3 --- GND
- Transistor OFF: output is high-impedance (Hi-Z). The pull-up resistor weakly drives the line HIGH.
- Transistor ON: output is connected to GND through a low-resistance path. The line is pulled LOW.
Why this matters — wired-OR / wired-AND
Because no driver can fight the line HIGH, multiple open-drain outputs can be tied together without contention. The line is HIGH only when everyone releases it; it goes LOW the moment any driver pulls. That gives you two equivalent logical interpretations:
- Wired-OR (active-low logic): the line goes LOW (asserted) when any device drives.
- Wired-AND (active-high logic): the line is HIGH only when every device releases.
In Verilog/VHDL, this is modeled with the wor or wand net types.
Where you'll see it in real systems
| Application | Why open-drain |
|---|---|
| I²C bus (SDA, SCL) | Multi-master arbitration: each master watches the line; if it sees LOW when it released, someone else is talking. Open-drain makes that detection possible without bus contention. |
| Shared interrupt lines | Many peripherals tie their IRQn outputs together; the CPU sees one line that goes low if any device wants attention. |
| Reset distribution | Power-good signals, watchdog outputs, and CPU resets can all tie into a common reset line; any source can hold the system in reset. |
| SPI fault pin | Multiple slaves sharing a single fault indicator without competing pull-ups. |
| Level shifting | Open-drain on one rail with a pull-up to a different rail moves a logic signal between voltage domains with a single resistor. |
Pull-up sizing — the math
The pull-up resistor turns the open-drain into an RC circuit during the rise. Given supply voltage VCC, capacitance C on the line (the bus has wires, pads, and input capacitances), and resistance R, the rise time from 0V to 70% of VCC is:
t_rise ≈ 1.2 × R × C
I²C standards prescribe maximum bus capacitance (e.g. 400 pF for Standard-mode) and minimum rise times (1000 ns for Standard, 300 ns for Fast). Working backward:
R_max = t_rise / (1.2 × C) = 1000 ns / (1.2 × 400 pF) ≈ 2.1 kฮฉ (Standard-mode worst case)
Smaller R = faster rise but more current sunk when LOW. Larger R = lower power but slower edges and worse noise margin. Typical I²C designs land at 4.7 kฮฉ for Standard-mode with reasonable bus loading; 1–2 kฮฉ for Fast-mode.
I²C waveform with open-drain
The bus line tracks the wired-OR of the drivers. The slow rise edges (when everyone releases) are the RC characteristic of the pull-up.
HDL modeling
// Open-drain output model — drive 0 or release
wire bus;
assign bus = (drive_low) ? 1'b0 : 1'bz;
// Wired-OR with multiple drivers
wor shared_line;
assign shared_line = device1_out;
assign shared_line = device2_out;
assign shared_line = device3_out;
// Pull-up modeling for simulation only
pullup (shared_line);
The pullup primitive is essential in simulation — without it, the line floats to X when all drivers release, which propagates through downstream logic and confuses debug.
Push-pull comparison
| Open-drain | Push-pull (CMOS) | |
|---|---|---|
| Drives HIGH | No (passive pull-up) | Yes (active PMOS) |
| Drives LOW | Yes | Yes |
| Multi-driver tie | Yes (no contention) | No (driver fight = damage) |
| Rise time | RC-limited (slow) | Active drive (fast) |
| Power | Continuous current through pull-up when LOW | Only switching power |
| Use case | Shared bus, level shift, multi-master | Point-to-point, high-speed |
Gotchas in real designs
- Long buses + small pull-up = slow edges. Adding more devices increases capacitance, which lengthens rise time. If you scope the bus and see rounded edges, the pull-up is too weak for the load.
- Multiple pull-ups in parallel. If a board has pull-ups on each card and all cards plug in, the effective resistance drops and current rises. I²C designs typically have a single bus pull-up.
- Idle current. Open-drain LOW means current through the pull-up — non-trivial in low-power designs. A 4.7 kฮฉ pull-up to 3.3V draws 700 ยตA continuously when held LOW.
- Mixed-rail traps. If your open-drain output is in a 1.8V domain but the line is pulled up to 3.3V, the receiving inputs must tolerate 3.3V — and the open-drain device must be able to hold off 3.3V when off (drain-to-source breakdown).
Interview-ready summary: Open-drain outputs let multiple devices share a wire because none can drive HIGH, only LOW or float. The bus's HIGH state comes from a pull-up resistor. The trade-off is slow rise edges (RC-limited) and continuous current when held LOW. Used everywhere multi-driver buses (I²C), shared signals (interrupts, resets), or level shifting are needed.
Comments (0)
Leave a Comment