Tri-state Buffers
High-Z & Bus Architecture
The third state — understand how multiple drivers share a wire without conflict, bus arbitration, and wired-OR using open-drain outputs.
Tri-state Buffer Truth Table
| Enable (OE) | Input (A) | Output (Y) |
|---|---|---|
| 1 (active) | 0 | 0 |
| 1 (active) | 1 | 1 |
| 0 (disabled) | X | Z (high-impedance) |
Interactive Bus Simulator — Bus Contention Demo
Bus Architecture — Multiple Drivers
A shared bus allows N sources to drive one wire, but only one at a time:
| Condition | Bus State | Safe? |
|---|---|---|
| No driver enabled | Z (floating) | Yes — but floating is unpredictable |
| Exactly one driver enabled | 0 or 1 | Yes ✓ |
| Two drivers, same value | 0 or 1 | Mostly (excess current) |
| Two drivers, opposite values | X (contention!) | No — circuit damage risk |
Open-Drain / Wired-AND
Open-drain outputs have no pull-up transistor — they can only pull the bus LOW. A shared pull-up resistor provides the HIGH level. Multiple open-drain drivers on one wire create wired-AND: LOW if ANY driver asserts low.
| Driver A | Driver B | Bus (wired-AND) |
|---|---|---|
| Z (released) | Z (released) | 1 (pull-up) |
| 0 (pulled low) | Z | 0 |
| Z | 0 | 0 |
| 0 | 0 | 0 |
Used in: I2C (SDA, SCL), SMBus, interrupt lines, JTAG TDO — any shared signal where multiple devices collaborate without contention risk.
Verilog — Tri-state Buffer & Bus
// Single tri-state buffer
module tri_buf (
input logic a, oe, // output enable, active-high
output logic y
);
assign y = oe ? a : 1'bz;
endmodule
// 8-bit tri-state bus driver
module bus_driver #(parameter W=8) (
input [W-1:0] data,
input oe,
output logic [W-1:0] bus
);
assign bus = oe ? data : {W{1'bz}};
endmodule
// Bidirectional bus (inout port)
module bidir_bus #(parameter W=8) (
inout logic [W-1:0] bus,
input logic [W-1:0] wdata,
output logic [W-1:0] rdata,
input logic we // write enable
);
assign bus = we ? wdata : {W{1'bz}};
assign rdata = bus; // always read bus
endmodule
// Open-drain (wired-AND) model
module open_drain (
input logic pull_low,
inout logic bus // shared with pull-up resistor
);
assign bus = pull_low ? 1'b0 : 1'bz;
endmodule
Frequently Asked Questions
What is a tri-state buffer?
A tri-state buffer has three output states: 0, 1, and Z (high-impedance/disconnected). When disabled (OE=0), the output is Z — electrically disconnected — allowing other drivers to use the wire.
What is bus contention and why is it dangerous?
Contention occurs when two enabled drivers drive opposite values, creating a short circuit. Large current flows, causing heat, data corruption, EMI, and possible IC damage. Bus arbitration prevents this.
What is open-drain and when is it used?
Open-drain can only pull LOW; a pull-up resistor provides HIGH. Multiple open-drain drivers create wired-AND (bus LOW if any pulls low). Used in I2C, interrupt lines, JTAG — safe multi-master sharing.