High-Speed Impedance-Compensated Pad Cell: Difference between revisions
No edit summary |
|||
| Line 181: | Line 181: | ||
The JSON netlist for the preslice can be found here: https://gitlab.libresilicon.com/generator-tools/librepdk/-/blob/master/designs/predriver_slice.json?ref_type=heads | The JSON netlist for the preslice can be found here: https://gitlab.libresilicon.com/generator-tools/librepdk/-/blob/master/designs/predriver_slice.json?ref_type=heads | ||
[[File:Predriver slice schematic.png|none|thumb|800x800px|Preslice Schematic]] | [[File:Predriver slice schematic.png|none|thumb|800x800px|Preslice Schematic]] | ||
== Predriver Slice Logic Specification == | |||
The pre-driver slice controls individual driver leg segments. It evaluates calibration bits (<tt>BIT_CAL_P</tt>, <tt>BIT_CAL_N</tt>), global tri-state enable (<tt>GLOBAL_EN</tt>), and On-Die Termination override (<tt>ODT_EN</tt>) to drive the gates of the output stage (<tt>GATE_P</tt> and <tt>GATE_N</tt>). | |||
{| class="wikitable" style="text-align:center;" | |||
|+ Predriver Slice Control Truth Table | |||
|- | |||
! BIT_CAL_P !! BIT_CAL_N !! GLOBAL_EN !! ODT_EN !! DATA_IN !! GATE_P <br/>(Active Low) !! GATE_N <br/>(Active High) !! Operating Mode / Output State | |||
|- | |||
| 0 || 0 || X || X || X || 1 (OFF) || 0 (OFF) || '''Leg Disabled / Uncalibrated (Hi-Z)''' | |||
|- | |||
| 1 || 1 || 0 || 0 || X || 1 (OFF) || 0 (OFF) || '''Global Tri-State / Standby (Hi-Z)''' | |||
|- | |||
| 1 || 1 || 1 || 0 || 1 || 0 (ON) || 0 (OFF) || '''Active Drive HIGH (Pull-Up)''' | |||
|- | |||
| 1 || 1 || 1 || 0 || 0 || 1 (OFF) || 1 (ON) || '''Active Drive LOW (Pull-Down)''' | |||
|- | |||
| 1 || 1 || X || 1 || X || 0 (ON) || 1 (ON) || '''On-Die Termination (ODT Active)''' | |||
|- | |||
| 1 || 0 || 1 || 0 || 1 || 0 (ON) || 0 (OFF) || '''Asymmetric Sourcing (Pull-Up Only)''' | |||
|- | |||
| 0 || 1 || 1 || 0 || 0 || 1 (OFF) || 1 (ON) || '''Asymmetric Sinking (Pull-Down Only)''' | |||
|} | |||
=== Mode Functional Descriptions === | |||
* '''Disabled / Uncalibrated:''' When calibration code bits are low, the slice is fully isolated from the output pad, preventing uncalibrated drive strength contributions. | |||
* '''Active Drive:''' Normal push-pull switching mode when <tt>GLOBAL_EN</tt> is asserted and <tt>ODT_EN</tt> is deasserted. | |||
* '''On-Die Termination (ODT):''' Asserts both pull-up (<tt>GATE_P=0</tt>) and pull-down (<tt>GATE_N=1</tt>) networks simultaneously, forming a center-tapped Thevenin termination load ($R_{\text{eq}} = Z_0$) at the pad. | |||
== 4. LibrePDK Physical Layout & Silicon Process Rules == | == 4. LibrePDK Physical Layout & Silicon Process Rules == | ||
Revision as of 21:45, 10 August 2026
High-Speed Impedance-Compensated Pad Cell Architecture & Specification
Document Status: Draft / Initial Specification
Target Process: LibrePDK (IHP SG13G2 / Generic CMOS)
Target Applications: High-Speed Interfaces (DDR4 SSTL/POD, PCIe Gen 1–3, High-Speed GPIO)
1. Overview & Problem Statement
Standard single-stage push-pull digital I/O drivers (consisting of a single large PMOS and NMOS transistor pair) are strictly insufficient for high-speed transmission lines ( single-ended or differential).
Uncompensated drivers suffer from severe non-linearities:
Impedance Mismatch & Reflections: Driver output impedance varies drastically across Process, Voltage, and Temperature (PVT) corners. Unmatched termination causes destructive signal reflections, ringing, and inter-symbol interference (ISI).
Lack of Dynamic Termination: Receiver modes require active On-Die Termination (ODT) to absorb incoming wave fronts without requiring discrete PCB resistors.
Lack of Drive-Strength Control: Variable trace lengths on PCBs require programmable output impedance to match line characteristics (, , , , , ).
To resolve these physical limitations, the next-generation LibreSilicon I/O library must move from static digital drivers to Segmented, PVT-Calibrated Output Drivers with Integrated ODT.
2. Core Architectural Pillars
An impedance-compensated pad cell consists of three mandatory functional subsystems:

2.1 Multi-Leg / Segmented Output Driver
Rather than a single monolithic transistor, the output driver array is divided into parallel driver legs (typically to ).
Each leg consists of a pull-up PMOS and pull-down NMOS in series with a precision poly-silicon resistor.
Leg parameters are sized such that the total leg resistance satisfies:
Enabling combinations of parallel legs provides discrete target output impedances:
| Enabled Legs () | Effective Driver Impedance | Application Target |
|---|---|---|
| 1 | High-impedance termination leg / Low-power drive | |
| 2 | ODT Receiver Mode (DDR4 half-strength) | |
| 4 | Standard PCB Line Match | |
| 5 | DDR4 Nominal Output Impedance | |
| 7 | High-drive / PCIe Nominal Output |
2.2 On-Die Termination (ODT) Logic
When operating as a receiver, the driver logic overrides normal push-pull operation. The pre-driver controls enable both the PMOS pull-up and NMOS pull-down legs simultaneously to form a center-tapped Thevenin equivalent termination or pull-up termination (e.g., POD12 for DDR4) matched to the trace impedance .
2.3 ZQ Calibration Engine (PVT Compensation)
Because silicon fabrication tolerances, operating temperature, and fluctuations alter and by up to , dynamic digital calibration is required:
An external precision resistor () is tied to a dedicated ZQ Pad.
An internal state machine (using an analog comparator and SAR or Up/Down counter) adjusts binary weighted calibration vectors (CAL_PCODE[N:0] and CAL_NCODE[N:0]).
The calibrated code vectors are distributed to all I/O pads across the die to trim active slice widths continuously.
3. Pre-Driver & Driver Netlist Topology (JSON)
To support automated Place & Route (PnR) inside LibreSilicon, the single-channel gate output format must be refactored into a segmented pre-driver slice array (driver_logic_segmented).
This is just a draft, we still have to re-introduce complex sub-components in LibrePDK
Segmented Driver Logic
{
"name": "driver_logic_segmented",
"nets": [
"VDD",
"VSS",
"IN",
"EN",
"OUT",
"FET_IN",
"ODT_EN",
"CAL_PCODE[0]", "CAL_PCODE[1]", "CAL_PCODE[2]", "CAL_PCODE[3]",
"CAL_NCODE[0]", "CAL_NCODE[1]", "CAL_NCODE[2]", "CAL_NCODE[3]",
"PMOS_OUT[0]", "PMOS_OUT[1]", "PMOS_OUT[2]", "PMOS_OUT[3]",
"NMOS_OUT[0]", "NMOS_OUT[1]", "NMOS_OUT[2]", "NMOS_OUT[3]"
],
"instances": {
"M_RX_P": {
"type": "pmos",
"nets": { "drain": "IN", "gate": "FET_IN", "source": "VDD", "bulk": "VDD" },
"current_multiplier": 1.0
},
"M_RX_N": {
"type": "nmos",
"nets": { "drain": "IN", "gate": "FET_IN", "source": "VSS", "bulk": "VSS" },
"current_multiplier": 1.0
},
"LEG_0_PREDRV": {
"type": "predriver_slice",
"nets": {
"VDD": "VDD",
"VSS": "VSS",
"DATA_IN": "OUT",
"GLOBAL_EN": "EN",
"ODT_EN": "ODT_EN",
"BIT_CAL_P": "CAL_PCODE[0]",
"BIT_CAL_N": "CAL_NCODE[0]",
"GATE_P": "PMOS_OUT[0]",
"GATE_N": "NMOS_OUT[0]"
}
},
"LEG_1_PREDRV": {
"type": "predriver_slice",
"nets": {
"VDD": "VDD",
"VSS": "VSS",
"DATA_IN": "OUT",
"GLOBAL_EN": "EN",
"ODT_EN": "ODT_EN",
"BIT_CAL_P": "CAL_PCODE[1]",
"BIT_CAL_N": "CAL_NCODE[1]",
"GATE_P": "PMOS_OUT[1]",
"GATE_N": "NMOS_OUT[1]"
}
},
"LEG_2_PREDRV": {
"type": "predriver_slice",
"nets": {
"VDD": "VDD",
"VSS": "VSS",
"DATA_IN": "OUT",
"GLOBAL_EN": "EN",
"ODT_EN": "ODT_EN",
"BIT_CAL_P": "CAL_PCODE[2]",
"BIT_CAL_N": "CAL_NCODE[2]",
"GATE_P": "PMOS_OUT[2]",
"GATE_N": "NMOS_OUT[2]"
}
},
"LEG_3_PREDRV": {
"type": "predriver_slice",
"nets": {
"VDD": "VDD",
"VSS": "VSS",
"DATA_IN": "OUT",
"GLOBAL_EN": "EN",
"ODT_EN": "ODT_EN",
"BIT_CAL_P": "CAL_PCODE[3]",
"BIT_CAL_N": "CAL_NCODE[3]",
"GATE_P": "PMOS_OUT[3]",
"GATE_N": "NMOS_OUT[3]"
}
}
},
"inputs": [
"OUT",
"EN",
"ODT_EN",
"FET_IN",
"CAL_PCODE[0]", "CAL_PCODE[1]", "CAL_PCODE[2]", "CAL_PCODE[3]",
"CAL_NCODE[0]", "CAL_NCODE[1]", "CAL_NCODE[2]", "CAL_NCODE[3]"
],
"outputs": [
"IN",
"PMOS_OUT[0]", "PMOS_OUT[1]", "PMOS_OUT[2]", "PMOS_OUT[3]",
"NMOS_OUT[0]", "NMOS_OUT[1]", "NMOS_OUT[2]", "NMOS_OUT[3]"
],
"pnr_params": {
"max_signal_metal": 3,
"y_corridor_tracks": 4,
"io_buffer_tracks": 2,
"rail_h": 1.2,
"num_rows": 4,
"pin_sides": {
"PMOS_OUT[0]": "top", "PMOS_OUT[1]": "top", "PMOS_OUT[2]": "top", "PMOS_OUT[3]": "top",
"NMOS_OUT[0]": "top", "NMOS_OUT[1]": "top", "NMOS_OUT[2]": "top", "NMOS_OUT[3]": "top",
"FET_IN": "top",
"EN": "bottom",
"ODT_EN": "bottom",
"OUT": "bottom",
"IN": "bottom",
"CAL_PCODE[0]": "left", "CAL_PCODE[1]": "left", "CAL_PCODE[2]": "left", "CAL_PCODE[3]": "left",
"CAL_NCODE[0]": "right", "CAL_NCODE[1]": "right", "CAL_NCODE[2]": "right", "CAL_NCODE[3]": "right"
}
}
}
Pre-Drive Slice
The JSON netlist for the preslice can be found here: https://gitlab.libresilicon.com/generator-tools/librepdk/-/blob/master/designs/predriver_slice.json?ref_type=heads

Predriver Slice Logic Specification
The pre-driver slice controls individual driver leg segments. It evaluates calibration bits (BIT_CAL_P, BIT_CAL_N), global tri-state enable (GLOBAL_EN), and On-Die Termination override (ODT_EN) to drive the gates of the output stage (GATE_P and GATE_N).
| BIT_CAL_P | BIT_CAL_N | GLOBAL_EN | ODT_EN | DATA_IN | GATE_P (Active Low) |
GATE_N (Active High) |
Operating Mode / Output State |
|---|---|---|---|---|---|---|---|
| 0 | 0 | X | X | X | 1 (OFF) | 0 (OFF) | Leg Disabled / Uncalibrated (Hi-Z) |
| 1 | 1 | 0 | 0 | X | 1 (OFF) | 0 (OFF) | Global Tri-State / Standby (Hi-Z) |
| 1 | 1 | 1 | 0 | 1 | 0 (ON) | 0 (OFF) | Active Drive HIGH (Pull-Up) |
| 1 | 1 | 1 | 0 | 0 | 1 (OFF) | 1 (ON) | Active Drive LOW (Pull-Down) |
| 1 | 1 | X | 1 | X | 0 (ON) | 1 (ON) | On-Die Termination (ODT Active) |
| 1 | 0 | 1 | 0 | 1 | 0 (ON) | 0 (OFF) | Asymmetric Sourcing (Pull-Up Only) |
| 0 | 1 | 1 | 0 | 0 | 1 (OFF) | 1 (ON) | Asymmetric Sinking (Pull-Down Only) |
Mode Functional Descriptions
- Disabled / Uncalibrated: When calibration code bits are low, the slice is fully isolated from the output pad, preventing uncalibrated drive strength contributions.
- Active Drive: Normal push-pull switching mode when GLOBAL_EN is asserted and ODT_EN is deasserted.
- On-Die Termination (ODT): Asserts both pull-up (GATE_P=0) and pull-down (GATE_N=1) networks simultaneously, forming a center-tapped Thevenin termination load ($R_{\text{eq}} = Z_0$) at the pad.
4. LibrePDK Physical Layout & Silicon Process Rules
When laying out the physical pad cell in LibrePDK, engineers must adhere to four strict silicon process guidelines:
4.1 Integrated Poly Resistors
Do NOT rely exclusively on transistor channel resistance for matching. Transistor channel resistance is non-linear with respect to drain-source voltage .
Place STI-isolated poly resistors in series with transistor drains to linearize the driver output impedance curve. Ensure consumes to of total leg impedance ( poly resistor + FET ).
4.2 Metal Routing Congestion & Layer Budget
Metal Layer Allocation: Simple digital pads use and . Segmented drivers routing 8–16 gate signals (PMOS_OUT[N], NMOS_OUT[N]) and calibration control buses MUST utilize (and where available).
Set "max_signal_metal": 3 in PnR configurations to prevent shorting routing tracks across standard cells.
4.3 Slew Rate Mismatch & Skew Control
Asymmetrical routing from the pre-driver data input OUT to individual leg slices creates switching skew between driver branches.
Inter-leg skew induces severe dynamic impedance transients and timing jitter during high-speed signal transitions.
Requirement: The Place & Route engine must enforce symmetric -tree routing for signal paths into LEG_0_PREDRV through LEG_N_PREDRV.
4.4 Pad Capacitance () and ESD Constraints
Paralleling multiple driver transistors increases total junction capacitance on the output pad pin.
Excessive degrades high-frequency edge rates.
Ensure pad layout uses multi-finger folded transitors placed in close proximity to ESD diodes to minimize parasitic substrate capacitance.
5. Implementation Roadmap for LibreSilicon Team
Step 1: Standardize predriver_slice Sub-Macro
Design and simulate the NOR/NAND gating matrix for a single pre-driver slice with ODT enable override.
Step 2: Poly Resistor Characterization
Extract exact sheet resistance () for poly silicon layer in IHP SG13G2 / LibrePDK to dimension the base leg.
Step 3: ZQ Calibration State Machine Netlist
Construct a centralized ZQ controller cell to generate CAL_PCODE and CAL_NCODE vectors across the IO ring.
Step 4: SPICE Corner Analysis
Run transient SPICE simulations across TT, FF, and SS process corners to verify output impedance holding tolerance within of target .