2. PCIe for DV Engineers - Physical Layer & LTSSM
Part 2 of the PCIe for DV Engineers series | Part 1: Architecture
The Physical Layer is the foundation of PCIe—responsible for link training, encoding, and electrical signaling. For DV engineers, this layer presents unique verification challenges around LTSSM state machines and protocol compliance.
Where the Physical Layer Fits
Before diving into PHY details, let's see where it sits in the PCIe stack:
The Physical Layer is the bottom layer—everything above depends on successful link training and reliable bit transmission.
Physical Layer Overview
The PHY handles four key functions:
- Electrical Signaling — Differential signaling, voltage levels, equalization
- Encoding/Decoding — 8b/10b (Gen1-2) or 128b/130b (Gen3+)
- Link Training — LTSSM state machine for link establishment
- Lane Management — Reversal detection, polarity inversion
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#e0f2fe', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#0369a1', 'lineColor': '#334155', 'fontSize': '13px'}}}%%
flowchart LR
subgraph PHY["Physical Layer"]
direction LR
subgraph LOGICAL["Logical Sub-block"]
direction TB
LTSSM["LTSSM"]
ENC["Encoder/
Decoder"]
SCR["Scrambler/
Descrambler"]
LTSSM --> ENC --> SCR
end
subgraph ELEC["Electrical Sub-block"]
direction TB
TX["Transmitter"]
RX["Receiver"]
CDR["CDR"]
TX ~~~ RX
RX --> CDR
end
end
SCR --> TX
CDR --> SCR
style PHY fill:#f0f9ff,stroke:#0369a1
style LOGICAL fill:#e0f2fe,stroke:#0369a1
style ELEC fill:#e0f2fe,stroke:#0369a1
style LTSSM fill:#0c4a6e,color:#fff,stroke:#0c4a6e
style ENC fill:#bae6fd,stroke:#0369a1
style SCR fill:#bae6fd,stroke:#0369a1
style TX fill:#7dd3fc,stroke:#0369a1
style RX fill:#7dd3fc,stroke:#0369a1
style CDR fill:#7dd3fc,stroke:#0369a1
Encoding Schemes
8b/10b (Gen1-2)
Each 8-bit byte becomes a 10-bit symbol, providing DC balance and clock recovery transitions.
D-codes: D0.0 to D31.7 (256 data characters)
K-codes: Control characters for framing
Key K-codes:
COM (K28.5) - Symbol alignment
SKP (K28.0) - Clock compensation
STP (K27.7) - Start of TLP
SDP (K28.2) - Start of DLLP
END (K29.7) - End of good packet
EDB (K30.7) - End of bad packet
DV Insight: Monitor running disparity in your encoder. Disparity errors cause link instability and are a common bug source.
128b/130b (Gen3+)
128 data bits + 2-bit sync header improves efficiency from 80% to ~98.5%:
- Sync header
01= Data block - Sync header
10= Ordered Set block - Data is scrambled (not encoded) for DC balance
| Encoding | Generations | Efficiency | Overhead |
|---|---|---|---|
| 8b/10b | Gen1-2 | 80% | 20% |
| 128b/130b | Gen3-5 | 98.5% | 1.5% |
| FLIT | Gen6 | ~94% | ~6% (FEC) |
LTSSM State Machine
The Link Training and Status State Machine (LTSSM) is the heart of PHY verification. It controls link initialization, training, power management, and error recovery.
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#e0f2fe', 'primaryTextColor': '#0f172a', 'primaryBorderColor': '#0369a1', 'lineColor': '#334155', 'fontSize': '12px'}}}%%
flowchart TB
subgraph TRAINING["Link Training"]
direction TB
DET(["Detect"])
POLL(["Polling"])
CFG(["Configuration"])
DET -->|"Receiver
Detected"| POLL
POLL -->|"TS1/TS2
Complete"| CFG
end
subgraph ACTIVE["Active State"]
L0(["L0
Normal Operation"])
end
subgraph RECOVERY_GRP["Recovery"]
REC(["Recovery"])
end
subgraph POWER["Power Management"]
direction TB
L0S(["L0s
Standby"])
L1(["L1
Low Power"])
L2(["L2
Aux Power"])
end
subgraph SPECIAL["Special States"]
direction TB
DIS(["Disabled"])
LB(["Loopback"])
HR(["Hot Reset"])
end
CFG -->|"Training
Success"| L0
L0 <-->|"Retrain"| REC
L0 -->|"ASPM"| L0S
L0S -->|"Exit"| L0
L0 -->|"PM"| L1
L1 -->|"Wake"| REC
L0 -->|"D3"| L2
L2 -->|"Wake"| DET
REC -->|"Fail"| DIS
DIS -->|"Enable"| DET
L0 -.->|"Test"| LB
L0 -.->|"Reset"| HR
HR -.-> DET
style DET fill:#bae6fd,stroke:#0369a1
style POLL fill:#bae6fd,stroke:#0369a1
style CFG fill:#bae6fd,stroke:#0369a1
style L0 fill:#22c55e,stroke:#16a34a,color:#fff
style REC fill:#f97316,stroke:#ea580c,color:#fff
style L0S fill:#fde68a,stroke:#f59e0b
style L1 fill:#fde68a,stroke:#f59e0b
style L2 fill:#fde68a,stroke:#f59e0b
style DIS fill:#fecaca,stroke:#ef4444
style LB fill:#e5e7eb,stroke:#6b7280
style HR fill:#e5e7eb,stroke:#6b7280
style TRAINING fill:#f0f9ff,stroke:#0369a1
style ACTIVE fill:#dcfce7,stroke:#22c55e
style RECOVERY_GRP fill:#fff7ed,stroke:#f97316
style POWER fill:#fefce8,stroke:#f59e0b
style SPECIAL fill:#f3f4f6,stroke:#6b7280
LTSSM States
| State | Purpose | DV Focus |
|---|---|---|
| Detect | Receiver presence detection | Timeout, detect sequence |
| Polling | Bit/symbol lock, polarity | TS1 exchange, compliance |
| Configuration | Width/speed negotiation | Lane numbering, TS1/TS2 |
| L0 | Normal operation | TLP/DLLP transmission |
| Recovery | Retrain, speed change | Error injection, equalization |
| L0s | Standby (~1us exit) | Entry/exit latency |
| L1 | Low power (longer exit) | Sub-states L1.1/L1.2 |
| L2 | Lowest power (aux only) | Beacon wake |
| Disabled | Link disabled | SW-initiated disable |
| Hot Reset | In-band reset | Reset bit in TS1 |
| Loopback | Testing mode | Compliance testing |
Training Sequences
TS1 and TS2 ordered sets negotiate link parameters during training:
TS1 Structure (16 symbols):
┌───────┬────────┬────────┬───────┬─────────┬───────┬────────┐
│ COM │ Link # │ Lane # │ N_FTS │ Rate ID │ Ctrl │ TS1 ID │
│ K28.5 │ │ │ │ │ Flags │ D10.2 │
└───────┴────────┴────────┴───────┴─────────┴───────┴────────┘
Control Flags: Hot Reset, Disable Link, Loopback,
Disable Scrambling, Compliance Receive
Ordered Sets Reference
| Ordered Set | Purpose | LTSSM State |
|---|---|---|
| TS1/TS2 | Link training | Polling, Configuration |
| SKP | Clock compensation | L0 (periodic) |
| EIEOS | Electrical Idle Exit | Exiting L0s/L1 |
| EIOS | Electrical Idle Entry | Entering L0s/L1 |
| FTS | Fast Training | L0s exit |
| SDS | Start Data Stream | Gen3+ alignment |
Verification Examples
LTSSM Coverage
covergroup ltssm_cg @(posedge clk);
state: coverpoint dut.ltssm_state {
bins detect = {DETECT_QUIET, DETECT_ACTIVE};
bins polling = {POLLING_ACTIVE, POLLING_CONFIG};
bins config = {CONFIG_LINKWIDTH_START, CONFIG_LANENUM_ACCEPT,
CONFIG_COMPLETE, CONFIG_IDLE};
bins active = {L0};
bins recovery = {RECOVERY_RCVRLOCK, RECOVERY_SPEED, RECOVERY_IDLE};
bins power = {L0S, L1, L2};
bins special = {DISABLED, LOOPBACK, HOT_RESET};
}
// Key transitions
trans: coverpoint dut.ltssm_state {
bins detect_poll = (DETECT_ACTIVE => POLLING_ACTIVE);
bins poll_config = (POLLING_CONFIG => CONFIG_LINKWIDTH_START);
bins config_l0 = (CONFIG_IDLE => L0);
bins l0_recovery = (L0 => RECOVERY_RCVRLOCK);
bins recovery_l0 = (RECOVERY_IDLE => L0);
}
endgroup
Speed Negotiation Test
task test_speed_downgrade();
// DUT: Gen4 capable, Partner: Gen1 only
dut_cfg.max_speed = GEN4;
partner_cfg.max_speed = GEN1;
partner_cfg.supported_speeds = 4'b0001;
trigger_ltssm_restart();
wait_for_state(L0);
// Verify downgrade occurred
`ASSERT_EQ(dut.current_speed, GEN1)
`ASSERT_EQ(dut.link_status.speed, 3'b001)
endtask
Lane Reversal Test
task test_lane_reversal();
// Connect lanes reversed (Lane 0 <-> Lane N-1)
env.connect_lanes_reversed();
trigger_ltssm_restart();
wait_for_state(L0);
`ASSERT_EQ(dut.lane_reversal_detected, 1'b1)
endtask
Common PHY Bugs
| Bug | Symptom | Test Strategy |
|---|---|---|
| Disparity errors | Link instability | Long traffic runs, check disparity |
| SKP timing | Clock drift failures | Verify SKP within 1538 symbols |
| Recovery loop | Link bouncing L0↔Recovery | Error injection, monitor retrain count |
| Lane numbering | Training fails at config | Multi-width testing |
| Speed fallback | Link down with legacy device | Mixed-gen partner testing |
| Timeout violations | Compliance failures | Verify LTSSM timeout values |
Key Takeaways
- LTSSM is the core state machine—comprehensive state/transition coverage is essential
- 8b/10b (Gen1-2) has 20% overhead; 128b/130b (Gen3+) has 1.5% overhead
- TS1/TS2 ordered sets negotiate link width, speed, and lane assignment
- Focus areas: state transitions, speed negotiation, error recovery, lane management
Next: Part 3 — Data Link Layer
Comments (0)
Leave a Comment