PCIe / PHYSICAL LAYER
How does a PCIe link move 128 billion bits a second down a copper trace?
Picture two people signalling across a valley with a torch. With two brightness levels, off and on, each flash is one bit. Flash faster and the far side starts to blur one flash into the next. Use four brightness levels and each flash carries two bits at the same speed, but in fog the levels are harder to tell apart, so you add a way to repair the odd mistake. That is the story of the PCIe physical layer from Gen 1 to Gen 7: flash faster (Gens 1 to 5), then use four levels and correct errors (Gens 6 and 7).
The simple guide comes first; then a signal scope where you add noise yourself, the line codes, the 256-byte flit and its error correction, link training step by step, and what Linux shows. The second half is for people who bring up boards, write drivers or read lspci for a living.
What claims does this page make? 5 points
- Spec rule: speeds, codes, the flit layout and link training come from the PCI Express Base Specification (members only, not read here) as its authors and PCI-SIG describe them in public talks and press releases, cited below. Where a public source gives sizes but not positions, the page says so.
- Simulation: the scope, the flit lab and the training experiments are simplified models (levels, Gaussian noise, a one-byte-a-group code); they show the idea, not a real channel or the real code's maths.
- Estimate: loss budgets, retry rates and latencies are the cited authors' figures, not measured here.
- Real hardware: the lspci lines are pciutils' formats; this page measured no link.
- Linux behaviour is quoted from its source, read on 2 October 2026.
The simple guide, in five ideas
- A lane is four wires. Two for each direction, as a differential pair: the receiver reads the difference between the two wires, so noise that hits both cancels. Both directions run at once. A x16 slot has sixteen lanes, and bytes are dealt across them like cards.
- There is no clock wire. The receiver recovers the timing from the data itself. That is why the bits are coded (Gens 1 and 2) or scrambled (all generations): a long run of zeros has no edges to lock onto.
- GT/s counts bits on one lane, not bytes. 32 GT/s is 32 billion bits a second, each way. From Gen 6 two bits share a symbol, so 64 GT/s is 32 billion symbols. Coding and checks take a share: 20% at Gens 1 and 2, under 2% at Gens 3 to 5, about 5.5% for the flit at Gens 6 and 7.
- Gens 6 and 7 send two bits a symbol. PAM4 uses four voltage levels instead of two. Gen 6 doubles the bit rate without making the signal change faster than Gen 5's, but each level sits closer to its neighbours, so errors are expected and corrected.
- A link trains itself. At power-on both ends start at 2.5 GT/s, agree on the lanes, then step up to the fastest speed both can hold, tuning their signal at each step. Software only sees the result.
Every other part of PCIe, the configuration reads, the packets and the DMA of the other chapters, rides on top of this and never sees which generation carried it.
Seven generations at a glance
Each generation doubled the bandwidth. Gen 3 got its doubling partly from a lighter code; Gen 6 from PAM4. Bandwidth here is one direction of a x16 link after line coding (and, for Gens 6 and 7, after the flit's error-checking bytes), in GB/s. PCI-SIG's press releases quote both directions before coding: 128 GB/s for Gen 5, 256 for Gen 6, 512 for Gen 7.
| Gen | Year | GT/s | Coding | Signal | Nyquist, GHz | x16, GB/s each way |
|---|---|---|---|---|---|---|
| 1 | 2003 | 2.5 | 8b/10b | NRZ | 1.25 | 4.0 |
| 2 | 2007 | 5 | 8b/10b | NRZ | 2.5 | 8.0 |
| 3 | 2010 | 8 | 128b/130b | NRZ | 4 | 15.8 |
| 4 | 2017 | 16 | 128b/130b | NRZ | 8 | 31.5 |
| 5 | 2019 | 32 | 128b/130b | NRZ | 16 | 63.0 |
| 6 | 2022 | 64 | flit | PAM4 | 16 | 121.0 |
| 7 | 2025 | 128 | flit | PAM4 | 32 | 242.0 |
- Nyquist frequency is the fastest the wire's voltage has to swing: half the symbol rate. It sets how much signal the board's copper loses. Gen 6 doubled the bits at Gen 5's 16 GHz because PAM4 sends half as many symbols; Gen 7 doubles the symbols again, to 32 GHz.
- PCIe 8.0 was announced on 5 August 2025: 256 GT/s, 1 TB/s both ways at x16, for release to members by 2028. Its signalling has not been announced; do not assume PAM4.
- Any card works in any slot. A link trains to the lower generation and the fewer lanes of its two ends. The lspci chapter has a slot-and-card lab that shows
LnkCapandLnkStafor any pair.
NRZ and PAM4 on a scope
The same bits, sent at the same symbol rate, two ways. NRZ (non-return
to zero) has two levels: one bit a symbol. PAM4 (pulse amplitude
modulation, four levels) has four: two bits a symbol, Gray coded so
neighbouring levels differ in one bit (00,
01, 11, 10 from the bottom).
Add noise and watch where the receiver, deciding at the dashed
thresholds, gets a symbol wrong (red dots).
The eye is what an oscilloscope shows when it overlays every symbol on one interval: the open space in the middle is the receiver's margin. PAM4 fits three eyes into the swing NRZ used for one, so each is a third as tall: about 9.5 dB less signal-to-noise (20·log103). Raise the noise until NRZ starts to fail; PAM4 failed long before. That is the price of Gen 6, and why it was the first generation to need forward error correction: its target is a first-bit error rate (FBER) of 10−6, where Gens 3 to 5 aimed at 10−12.
Two further tricks from Gen 6 do not show here: precoding, which stops one bad decision in an equalizer from turning into a burst, and the Gray code itself, which makes the usual mistake (a neighbouring level) cost one bit, not two.
Line codes: 8b/10b, 128b/130b, and none
| 8b/10b (Gens 1, 2) | 128b/130b (Gens 3-5) | Flit mode (Gens 6, 7) | |
|---|---|---|---|
| What is sent | each byte as a 10-bit symbol from a table | a 2-bit sync header, then 128 scrambled bits | 256-byte flits, scrambled; no per-block header |
| Overhead | 20% | 1.5% | the flit's 8-byte CRC and 6-byte FEC, about 5.5% (242 of 256 bytes carry packets and link information) |
| Clock recovery | at most 5 equal bits in a row, by the code | by the scrambler (statistically) | by the scrambler |
| Control | special symbols (K codes), such as COM | header 01: an ordered set; 10: data | ordered sets between flits |
| Errors caught by | packet CRCs (LCRC, ECRC) | packet CRCs | the flit's FEC and CRC |
- 8b/10b (Widmer and Franaszek, IBM, 1983) keeps the line balanced: as many ones as zeros over time, so it can pass a series capacitor, and never more than five equal bits in a row, so the receiver's clock never drifts far. It also scrambles, with x16+x5+x4+x3+1.
- 128b/130b: Gen 3 needed double Gen 2's bandwidth but chose 8 GT/s, not 10, because 8 GT/s fitted mainstream silicon; dropping 8b/10b's 20% made up the rest. Each lane scrambles with x23+x21+x16+x8+x5+x2+1, seeded differently per lane, and the two-bit header tells data blocks from ordered sets (training sets, SKP for clock compensation).
- Flit mode drops the header and the per-packet framing and CRC: packets are packed into fixed flits that carry their own checks. Once a link negotiates flit mode it stays in it at every speed, even 2.5 GT/s.
The 256-byte flit and its error correction
A flit (flow control unit) is the fixed-size block every Gen 6 and Gen 7 link sends: 236 bytes of packets, 6 of link information, an 8-byte CRC and 6 bytes of FEC. The FEC is three interleaved codes; each repairs one bad byte. Bytes are dealt to the three groups in turn, so a burst of up to three neighbouring bad bytes puts one in each group, and all three are repaired. Press bytes to corrupt them (the arrow keys move between them), or send a burst:
Pick a byte to see its part here.
Try a burst of 3, then 4. Four bad bytes in a row put two in one group; the FEC cannot repair it and the CRC catches it (an 8-byte CRC detects any 8 bad bytes for certain). The receiver then asks for the flit again. The numbers that made this design work, from the specification's lead author:
- At an FBER of 10−6, about 5 flits in a million need a retry: about 0.05% of the bandwidth.
- FEC repair plus the CRC check take under 2 ns. The whole change from Gen 5 had to add under 10 ns to transmit and receive together.
- A retry resends only the bad flit when it can (a selective NAK), or that flit and those after it (go back N). Idle (NOP) flits have no sequence number and are never resent.
- On a x16 link three bytes in a row on one lane are in three groups too, so a burst of up to 16 bit times on one lane hits at most one byte a group.
The sizes and their order are published; the byte positions of the packet and link bytes (0-235, 236-241) are inferred from them, and the lab's "byte mod 3" grouping is a simplification of the real interleave. CXL 3's 256-byte flit keeps this CRC and FEC but lays out the rest its own way: a 2-byte header, then CXL.io packets or CXL.cache and CXL.mem slots (see the CXL chapter).
Experiments
One link, from power-on to L0 and back: the link training state machine (LTSSM) as both ends run it.
Experiment
This "What if" step ran on its own copy; the panels show that copy.
For professionals: equalization, channel loss and retimers
Copper loses high frequencies more than low ones, so a sharp edge arrives smeared into the next symbol. Equalization undoes that: the transmitter pre-shapes its signal (de-emphasis, a weaker level after a run of equal bits, and preshoot, a stronger one before an edge), and the receiver adds its own filters (CTLE, DFE). Gen 3 introduced a three-tap transmitter filter tuned during training; Gen 6 uses four taps.
Training starts from one of eleven presets, P0 to
P10 (P10 is for compliance testing). The values below are the ones
pciutils decodes. The presets a port starts training with are in its
Lane Equalization Control registers (the Secondary PCI Express
capability for 8 GT/s, the 16 and 32 GT/s Physical Layer capabilities
above that). LnkCtl2: … Compliance Preset/De-emphasis
in lspci -vv is something else: the preset a port sends
while a compliance test runs, not the one the live link uses.
| Preset | P0 | P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9 |
|---|---|---|---|---|---|---|---|---|---|---|
| De-emphasis, dB | −6 | −3.5 | −4.4 | −2.5 | 0 | 0 | 0 | −6 | −3.5 | 0 |
| Preshoot, dB | 0 | 0 | 0 | 0 | 0 | 1.9 | 2.5 | 3.5 | 3.5 | 3.5 |
- Phase 0: the downstream port (the root port side) tells the device which preset to start with.
- Phase 1: both ends send with those presets until the link works well enough to talk.
- Phase 2: the upstream end's receiver asks the downstream port's transmitter for changes, over and over, until its errors are low enough.
- Phase 3: the same in the other direction.
The conventional, full sequence equalizes each rate from 8 GT/s up
in turn, which is why Linux has a separate capability for each
(PCI_EXT_CAP_ID_PL_16GT, _32GT,
_64GT, each with its lane equalization registers). PCIe
5.0 added two optional shortcuts that both ends must support: an
equalization bypass that goes from 2.5 GT/s straight
to the highest common rate and equalizes only there, and no
equalization needed, for a channel short and clean enough to
skip it (lspci: Physical Layer 32.0 GT/s,
Phy32Cap: EqualizationBypass+ NoEqualizationNeeded+).
Equalization is the step that fails on a poor channel; the second
experiment above shows the result.
The channel loss budget says how much a link may
lose end to end at its Nyquist frequency: 36 dB at 16 GHz for Gen 5
(about 9 dB for the processor package, 16 for the board, 1.5 for the
connector and 9.5 for the card), and 32 dB at 16 GHz for Gen 6,
because PAM4's smaller eyes need more of the signal to arrive. When
a trace is too long, a retimer recovers the bits
and sends them again freshly equalized; a link may have at most two,
and lspci's LnkSta2 reports them
(Retimer+ 2Retimers-). A redriver only amplifies, noise
included.
Both ends also need the same idea of time: a 100 MHz reference
clock, shared (CommClk+ in lspci) or separate, often
with spread-spectrum clocking that wobbles it by up to 0.5% at about
30 kHz to spread its radio emissions.
Gen 6, Gen 7, optics and Gen 8
- PCIe 6.0 (11 January 2022): 64 GT/s, PAM4, flits with FEC, and the new L0p power state, which turns lanes off while data keeps flowing on the rest. The old L0s light sleep is not allowed once a link uses flit mode. It stays compatible with every earlier generation.
- PCIe 7.0 (11 June 2025): 128 GT/s, still PAM4 and flits, 512 GB/s both ways at x16. Its Nyquist frequency doubles to 32 GHz, and the loss budget is quoted as 36 dB at 32 GHz, so boards need better materials, shorter traces or retimers.
- Optics: PCI-SIG formed an optical workgroup in August 2023, and on 11 June 2025 published the Optical Aware Retimer ECN for PCIe 6.4 and 7.0, the first standard way to carry PCIe over fibre, through retimers.
- PCIe 8.0 (announced 5 August 2025): 256 GT/s and 1 TB/s both ways at x16, due to members by 2028. The announcement lists new connectors and latency and FEC targets as open work; the signalling is not public.
What Linux shows
The link's state lives in the device's PCI Express capability. lspci decodes it (pciutils 3.15):
LnkCap: Port #0, Speed 32GT/s, Width x16, ASPM L1, Exit Latency L1 <16us LnkSta: Speed 16GT/s (downgraded), Width x16 LnkCap2: Supported Link Speeds: 2.5-32GT/s, Crosslink- Retimer+ 2Retimers+ DRS- LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete+ EqualizationPhase1+ EqualizationPhase2+ EqualizationPhase3+ LinkEqualizationRequest- Retimer+ 2Retimers- CrosslinkRes: unsupported, FltMode-
sysfs has the same in words: /sys/bus/pci/devices/0000:01:00.0/current_link_speed
reads 16.0 GT/s PCIe, max_link_speed
32.0 GT/s PCIe, and current_link_width
16. When a device is held back by a slower link
anywhere above it, the kernel says so once at boot
(__pcie_print_link_status() in drivers/pci/pci.c):
pci 0000:01:00.0: 126.016 Gb/s available PCIe bandwidth, limited by 8.0 GT/s PCIe x16 link at 0000:00:01.0 (capable of 252.048 Gb/s with 16.0 GT/s PCIe x16 link)
Computed from the kernel's code for a Gen 4 x16 card behind a Gen 3 x16 port, not captured from hardware; the addresses are examples. A link in flit mode adds , in Flit mode.
- The kernel's bandwidth is
width × PCIE_SPEED2MBS_ENC(speed): 8b/10b and 128b/130b taken off, but nothing for flits, so it counts Gen 6 as the full 64 Gb/s a lane. - 128 GT/s is code 8, not 7. Speed code 7 is reserved; 8 means "128 GT/s or higher", with the exact rate in a new capability. pciutils 3.15 prints
128GT/s; Linux's speed table, read on 2 October 2026, stops at 64 GT/s, so a Gen 7 link readsUnknownincurrent_link_speed. A patch that used 7 was turned down in February 2026. - On boards with a Synopsys DesignWare controller (many Arm systems),
/sys/kernel/debug/dwc_pcie_*/ltssm_statusshows the LTSSM state by name, such asL0 (0x11): the states in the experiments above.
Sources
- D. Das Sharma (Intel, PCI-SIG board), "PCI Express 6.0" talk, IEEE San Diego, 27 August 2021 (generations, PAM4 levels and Gray code, FBER, retry and bandwidth figures, latency targets) and OFA Workshop 2022 (flit layout, FEC and CRC, replay, L0p, L0s in flit mode); IEEE Micro 41(1), 2021.
- PCI-SIG press releases: PCIe 5.0 (29 May 2019), 6.0 (11 January 2022), 7.0 and the Optical Aware Retimer ECN (11 June 2025), 8.0 (5 August 2025); the optical workgroup (2 August 2023).
- Synopsys, "PCIe 6.0 verification of FEC and CRC" (2022): CRC and FEC coverage, groups on a x16 link. Wikipedia's Compute Express Link article: the CRC and FEC byte positions.
- A. X. Widmer and P. A. Franaszek, "A DC-balanced, partitioned-block, 8B/10B transmission code", IBM J. Res. Dev. 27(5), 1983. Embedded Computing Design (Synopsys, 2017) for Gen 3's rate and scrambler; Teledyne LeCroy (2021) and Granite River Labs for the equalization phases; Astera Labs and Signal Integrity Journal (2024) for loss budgets; Skyworks for reference clocks.
- Linux, read on 2 October 2026 (7.3-rc5):
drivers/pci/pci.h(PCIE_SPEED2MBS_ENC),drivers/pci/pci.c(__pcie_print_link_status),drivers/pci/probe.c(pcie_link_speed),drivers/pci/pci-sysfs.c,include/uapi/linux/pci_regs.h,drivers/pci/controller/dwc/pcie-designware.h(enum dw_pcie_ltssm); the 128 GT/s review on the mailing list. pciutilsls-caps.c(speed names,(downgraded), presets). - The PCI Express Base Specification (PCI-SIG, members only) is not hosted or quoted here.
tests/iommu-pcie-phy.test.mjschecks this page's table, the scope's coding and the flit lab against the model.