콘텐츠로 이동

Module 02 — 3-Layer Architecture

학습 목표

이 모듈을 마치면:

  • Diagram PCIe 의 3 계층 (Transaction / Data Link / Physical) 과 sub-block 을 그릴 수 있다.
  • Distinguish 각 layer 가 처리하는 packet 단위 (TLP / DLLP / Ordered Set + symbol) 을 구분한다.
  • Trace memory write 가 application → TLPDLL 추가 (sequence #, LCRC) → PHY 추가 (STP/END, encoding) 까지 가는 흐름을 추적한다.
  • Apply 각 layer 의 책임 분리가 디버그/검증에서 어떤 이점을 주는지 시나리오에 매핑한다.
  • Justify PCIe 의 "신뢰성은 DLL 의 일" 이라는 명제를 PHY BER ≠ 0 이라는 사실과 함께 정당화한다.

사전 지식

  • Module 01 (point-to-point + lane 모델)
  • 일반 OSI 계층 개념

1. Why care? — 이 모듈이 왜 필요한가

1.1 시나리오 — LCRC error vs ECRC error 의 진단

당신은 PCIe error log:

PCI Express: Correctable error: LCRC error

이 한 줄이 즉시 알려주는 것: - L in LCRC = Link LayerDLL (Data Link Layer) 책임. - CorrectableDLLACK/NAK retry 가 자동 복구. - 즉 복구됨, 단 frequency 증가PHY 신호 품질 문제 의심.

vs ECRC error: - E = End-to-end → Transaction Layer 책임. - Endpoint 의 TLP 생성 또는 RC 의 receive 문제.

같은 "CRC error" 라도 layer 가 다르면 완전히 다른 진단. Layer 모델 모르면 혼동 → 잘못된 RTL 영역 디버그.

모든 PCIe spec 의 기능 분류와 디버그 분류가 "어느 layer 의 일?" 에서 출발합니다. AER (Module 07) 의 error class, retry 메커니즘 (Module 04), LTSSM (Module 05) 모두 layer 책임이 명확히 분리된 상태에서 정의됩니다.

이 모듈의 어휘 — Transaction / Data Link / Physical, TLP / DLLP / Ordered Set, ECRC / LCRC — 가 이후 모든 packet trace, scoreboard 비교, AER 카운터 해석의 기본 단위. 이 layer 모델을 머리에 정확히 넣어 두면 "이 에러는 LCRC error" 라는 한 줄로 즉시 어느 layer 의 어느 메커니즘이 동작했는지 그릴 수 있게 됩니다.


2. Intuition — 국제 운송의 3 단계 비유와 한 장 그림

💡 한 줄 비유

PCIe 3 layer국제 화물 운송의 3 단계.
Transaction = 송장 + 화물 명세 (무엇을 어디로).
Data Link = 운송중 분실/파손 보험 (sequence #, LCRC, ACK/NAK).
Physical = 실제 운송수단 (트럭, 비행기 = serial link, equalization).
각 단계가 자기 책임만 처리. Transaction layer 는 운송수단을 모르고, Physical 은 화물 내용을 모름.

한 장 그림 — 송신 path 와 layer 별 wrapper

Sender — wrapper 추가Receiver — wrapper 제거TXPLRXPLRXDLLTXDLLApphost PA 0x10000 에 64 B writeTransaction LayerTLP = Hdr + Payload + (ECRC?)Data Link Layer+Seq# +LCRC · ACK/NAKPhysical LayerSTP/END · Scramble+EncodeLane stripe · SerDesPhysical LayerFrame detect · Decode+DescrambleLane de-stripe · CDR + EQData Link LayerLCRC verify · ACK/NAK 송신Transaction LayerTLP 분해 + ECRC 검증App메모리에 적용 TLPTLP+Seq+LCRC, DLLPwire ACK/NAK
Sender — wrapper 추가Receiver — wrapper 제거TXPLRXPLRXDLLTXDLLApphost PA 0x10000 에 64 B writeTransaction LayerTLP = Hdr + Payload + (ECRC?)Data Link Layer+Seq# +LCRC · ACK/NAKPhysical LayerSTP/END · Scramble+EncodeLane stripe · SerDesPhysical LayerFrame detect · Decode+DescrambleLane de-stripe · CDR + EQData Link LayerLCRC verify · ACK/NAK 송신Transaction LayerTLP 분해 + ECRC 검증App메모리에 적용 TLPTLP+Seq+LCRC, DLLPwire ACK/NAK

세 layer 가 각자의 wrapper 를 추가/제거. wrapper 추가는 송신, 제거는 수신 — 이 layered 구조 덕에 디버그가 직선화됩니다.

왜 이렇게 설계됐는가 — Design rationale

PCIe 가 풀어야 하는 세 문제는 서로 다른 시간 척도 에 있습니다.

  1. 무엇을 어디로 보낼까 (transaction) — μs ~ ms 단위, application 의 의도.
  2. 이 packet 이 깨졌나, 다시 보낼까 (data link) — ns ~ μs 단위, 매 packet.
  3. 이 bit 가 1 인가 0 인가 (physical) — ps ~ ns 단위, 매 symbol.

세 문제를 한 모듈로 풀려고 하면 디버그가 불가능 — 시간 단위가 다른 사건이 섞여 보입니다. 분리된 layer + 명시적 wrapper 가 이 문제를 풀고, 각 layer 가 다른 hardware/protocol 발전 속도를 흡수할 수 있게 만듭니다 (예: Gen6 의 PAM4/FEC 변경은 PHY 만 손대고 TLP 는 그대로).


3. 작은 예 — 64 byte MWr 한 개가 3 layer 를 내려가는 과정

가장 단순한 시나리오. Device core 가 host PA 0x1000064 byte 를 write.

Device Corehost PA 0x10000 에 64 B write 요청TL (tx)MWr TLP 생성 (Fmt=10, Type=00000,Length=16 DW, Addr=0x10000, payload 64 B)FC credit 차감 (P), ECRC 옵션DLL (tx)Seq# = 0x123, LCRC over [Seq# + TLP]Replay Buffer 에 저장PL (tx)STP + TLP + END framing128b/130b + scramble + lane stripeSerDes → wireWirePL (rx)CDR · lane de-stripe130b→128b decode · descramble · frame detectDLL (rx)LCRC 검증OK → ACK DLLP / FAIL → NAK DLLPTL (rx)FC credit 반환 · TLP 처리memory write 적용
Device Corehost PA 0x10000 에 64 B write 요청TL (tx)MWr TLP 생성 (Fmt=10, Type=00000,Length=16 DW, Addr=0x10000, payload 64 B)FC credit 차감 (P), ECRC 옵션DLL (tx)Seq# = 0x123, LCRC over [Seq# + TLP]Replay Buffer 에 저장PL (tx)STP + TLP + END framing128b/130b + scramble + lane stripeSerDes → wireWirePL (rx)CDR · lane de-stripe130b→128b decode · descramble · frame detectDLL (rx)LCRC 검증OK → ACK DLLP / FAIL → NAK DLLPTL (rx)FC credit 반환 · TLP 처리memory write 적용

단계별 의미

Step 누가 무엇을 추가/제거
Device core → TL "write 64B" 의도 → MWr TLP application 의 추상화
TL Header (Fmt/Type/Address/Length) + payload + opt ECRC TLP 의 자기-기술적 (self-descriptive) packet
TL FC credit 차감 (P credit) receiver 의 buffer 만큼만 송신 (Module 04)
DLL Seq# (12-bit) 순서 보장 + Replay 단위
DLL LCRC (32-bit) over [Seq# + TLP] hop-level 무결성
DLL Replay Buffer 저장 ACK 받기까지 보관
PL STP framing token TLP 의 시작 표시
PL 128b/130b encoding + scrambling DC balance + EMI 분산
PL Lane stripe (byte-wise round-robin) x4/x16 의 lane 활용
PL → wire SerDes 직렬화 → differential pair analog 신호
wire → PL (rx) CDR + EQ + 역방향 stripe/decode lane 별 박자 복원
DLL (rx) LCRC 검증 → ACK DLLP 송신 reliability 응답
TL (rx) TLP 분해 → memory write 적용, FC credit 반환 의도 실현
// Sender 측 layer wrapper 의 의사코드 — 각 layer 가 자기 책임만
struct tlp build_tlp(struct request *req) {
    return (struct tlp){
        .hdr = encode_header(MWr, req->addr, req->length),
        .payload = req->data,
        .ecrc = compute_ecrc_optional(req),
    };
}
struct dll_pkt wrap_dll(struct tlp t, uint16_t seq) {
    return (struct dll_pkt){
        .seq  = seq,
        .tlp  = t,
        .lcrc = crc32_lcrc(seq, t),  // Seq# + TLP 위로
    };
}
void send_phy(struct dll_pkt p) {
    emit_token(STP);
    emit_scrambled_encoded(p, &lane_stripe);  // 128b/130b + lane round-robin
    emit_token(END);
}

여기서 잡아야 할 두 가지

(1) 각 layer 가 자기 책임만 처리한다 — Transaction layer 는 PHYBER 을 모르고, Physical 은 TLP 의 의미를 모른다. 이 추상화 경계가 디버그에서 "어느 layer 의 증상?" 라는 첫 질문의 정당성.
(2) Wrapper 는 양방향 비대칭이다 — 송신은 추가, 수신은 제거. TL/DLL/PL 마다 어떤 wrapper 가 추가됐는지 알아야 packet trace 의 byte stream 을 layer 별로 분해해서 읽을 수 있다.


4. 일반화 — 3 layer 의 책임 분리와 packet 단위

4.1 각 layer 의 packet 단위

Layer Packet 길이
Transaction TLP 가변 (header 12-16B + payload 0..4096B + opt ECRC 4B) MRd, MWr, CplD, CfgRd0/1
Data Link DLLP 8 byte (header + LCRC) Ack, Nak, FC Init/Update, PM_*, Vendor
Physical Ordered Set + Symbol 가변 TS1/TS2, FTS, EIOS, EIEOS, SDS, SKP

DLLP 는 Transaction Layer 가 보지 않음. TLPPHY 가 보지 않고 그저 byte stream.

4.2 책임 매트릭스

책임 TL DLL PL
무엇을 어디로 (address, BDF)
Posted/NP/Cpl ordering
Flow Control credit (DLLP 운반)
ECRC (end-to-end)
Sequence Number
LCRC (hop-level)
ACK/NAK + Replay
DL_Active state
Framing (STP/END/SDP)
Encoding/Scrambling
Lane stripe + SerDes
LTSSM + EQ

모든 PCIe link 의 retransmission 은 DLL 책임. PHYBER 이 아무리 낮아도 0 이 아니므로 packet-level reliability 가 필요.

4.3 디버그 흐름의 직선화

증상 발견어느 layer 의 일인가?TLP type / address 잘못 → TLLCRC error / replay 빈발 → DLLLink 자체가 안 올라옴 → PL (LTSSM)Specific BAR 만 fail → TL (header field) + Module 06AER counter 증가 → AER mapping → 해당 layer
증상 발견어느 layer 의 일인가?TLP type / address 잘못 → TLLCRC error / replay 빈발 → DLLLink 자체가 안 올라옴 → PL (LTSSM)Specific BAR 만 fail → TL (header field) + Module 06AER counter 증가 → AER mapping → 해당 layer

이 한 단계의 분류가 80% 의 디버그 케이스 를 해결합니다.


5. 디테일 — TL / DLL / PL 의 내부 block 과 규칙

5.1 3 Layer 한 장 뷰

Application / Device Core(driver, NIC engine, …)Transaction Layer· TLP 생성/분해 (header + payload + ECRC)· Flow Control credit 관리· TLP type / routing / address translation· Ordering rules (P/NP/Cpl)Data Link Layer· Sequence Number 부여· LCRC 계산 / 검증· ACK/NAK 송신, Replay Buffer· DLLP (FC update, ACK/NAK, Power)· Link state (DL_Inactive / Init / Active)Physical Layer· Framing (STP/END, SDP/EDS)· Encoding (8b/10b → 128b/130b → PAM4/FLIT)· Scrambling, Lane stripe· Serializer/Deserializer (SerDes)· LTSSM (link training)· Equalization, CDR· Ordered Sets (TS1/TS2, EIOS, …) memory request, completion, messageTLPTLP + Seq# + LCRC, DLLP
Application / Device Core(driver, NIC engine, …)Transaction Layer· TLP 생성/분해 (header + payload + ECRC)· Flow Control credit 관리· TLP type / routing / address translation· Ordering rules (P/NP/Cpl)Data Link Layer· Sequence Number 부여· LCRC 계산 / 검증· ACK/NAK 송신, Replay Buffer· DLLP (FC update, ACK/NAK, Power)· Link state (DL_Inactive / Init / Active)Physical Layer· Framing (STP/END, SDP/EDS)· Encoding (8b/10b → 128b/130b → PAM4/FLIT)· Scrambling, Lane stripe· Serializer/Deserializer (SerDes)· LTSSM (link training)· Equalization, CDR· Ordered Sets (TS1/TS2, EIOS, …) memory request, completion, messageTLPTLP + Seq# + LCRC, DLLP

5.2 Transaction Layer (TL) 책임

from device coreTLP Builderheader, payload, ECRCFlow Controlcredit available 확인 후 송신OrderingP / NP / Cpl 규칙TLP Routing / TypeMRd / MWr / CfgRd / CfgWr / Cpl / MsgData Link Layer TLP
from device coreTLP Builderheader, payload, ECRCFlow Controlcredit available 확인 후 송신OrderingP / NP / Cpl 규칙TLP Routing / TypeMRd / MWr / CfgRd / CfgWr / Cpl / MsgData Link Layer TLP
기능 핵심
TLP 생성 Fmt + Type + Length + Address (or BDF) + payload
Flow Control P / NP / Cpl 별 header credit + data credit 추적, FC DLLP 로 갱신
Ordering Posted (P) ↔ Non-Posted (NP) ↔ Completion (Cpl) 의 strict ordering 규칙 (PCI legacy 호환)
ECRC (optional) end-to-end CRC. 라우팅 노드에서 변경 안 됨.
Address translation ATS 사용 시 IOVA → PA 변환 결과 캐시
from TL: TLPSeq# 부여12-bit sequence number 0..4095LCRC 계산32-bit Link CRCReplay Buffer 저장ACK 받기까지 보관ACK/NAK 처리받은 순서대로 ACK, error 시 NAK + replayDLLP 송신FC update, ACK/NAK, PM_*Physical Layer TLP + Seq# + LCRC, DLLP
from TL: TLPSeq# 부여12-bit sequence number 0..4095LCRC 계산32-bit Link CRCReplay Buffer 저장ACK 받기까지 보관ACK/NAK 처리받은 순서대로 ACK, error 시 NAK + replayDLLP 송신FC update, ACK/NAK, PM_*Physical Layer TLP + Seq# + LCRC, DLLP
기능 핵심
Sequence Number 12-bit, modulo 4096. 송신 순서대로 부여, receiver 의 Next Receive Seq# 와 비교
LCRC 32-bit, TLECRC 와 별도. Hop-level 무결성
Replay Buffer Sender 가 ACK 받을 때까지 TLP 저장. NAK 시 그 sequence 부터 재전송
ACK/NAK DLLP 로 송신. ACK = 누적 ACK (해당 seq 까지 수신), NAK = error 발생
DL Control State DL_Inactive → DL_Init → DL_Active. DL_Active 에서만 TLP 송수신

모든 PCIe link 의 retransmission 은 DLL 책임.

5.4 Physical Layer (PL) 책임

from DLL: TLP + Seq# + LCRC, DLLPFramingSTP/END (Gen1/2), SDP/EDS (Gen3+)ScramblingLFSR-based, EMI 분산Encoding8b/10b (Gen1/2) or 128b/130b (Gen3+)Lane Stripebyte-wise round-robin 분산SerDes직렬화 → differential pairLTSSMlink bring-up, EQ, recoveryOrdered SetsTS1/TS2, FTS, EIOS, SKPWire / connector analog signal
from DLL: TLP + Seq# + LCRC, DLLPFramingSTP/END (Gen1/2), SDP/EDS (Gen3+)ScramblingLFSR-based, EMI 분산Encoding8b/10b (Gen1/2) or 128b/130b (Gen3+)Lane Stripebyte-wise round-robin 분산SerDes직렬화 → differential pairLTSSMlink bring-up, EQ, recoveryOrdered SetsTS1/TS2, FTS, EIOS, SKPWire / connector analog signal
기능 핵심
Framing TLP 의 시작/끝 표시 (STP=Start TLP, END), DLLP (SDP=Start DLLP, EDS=End Data Stream)
Scrambling EMI 줄이기 위해 LFSR XOR. 양 끝이 같은 LFSR seed 로 동기화
Encoding DC balance, clock recovery 가능한 transition 보장
Lane Stripe x16 link 에서 byte 0 → lane 0, byte 1 → lane 1, …, byte 15 → lane 15, byte 16 → lane 0
SerDes Tx FIFO + serializer + driver / Rx CDR + deserializer + EQ
LTSSM 11 state link training + recovery + L0s/L1 entry
Ordered Sets TS1/TS2 = training, FTS = fast training, EIOS = electrical idle, SKP = clock comp

차동 신호 (Differential Signaling) 의 노이즈 제거 — 정량 예시

한 lane 은 TX 2 가닥 + RX 2 가닥 = 총 4 핀 (TX+/TX-/RX+/RX-). 송신 시 데이터를 정상 신호(+) 와 역상 신호(-) 두 개로 나눠 한 쌍으로 송출.

예: 송신 (+0.1V, -0.1V) → 차이 = 0.2V = 1 로 해석.

중간에 외부 노이즈가 두 선에 동시에 +0.5V 더해진다고 가정 → 도착 시 (+0.6V, +0.4V).

수신 측은 두 신호의 차이만 계산: 0.6 − 0.4 = 0.2V. 노이즈는 상쇄되고 원래 값 그대로.

덕분에 PCIe수백 mV 수준의 매우 작은 전압 차이 로도 안정적 통신 가능 — 저전압 + 고속화의 토대.

8b/10b vs 128b/130b — encoding 의 본질

연속된 0 또는 1 의 공포: 00000000 처럼 변화 없는 데이터가 길게 흐르면 수신 측 CDR 이 박자 (clock edge) 를 잃어 동기화 실패.

8b/10b (Gen1, Gen2) — Lookup Table 방식:

  • 8 bit 데이터 → 사전에 약속된 10 bit 코드로 변환.
  • 연속된 0 또는 1 의 길이를 5 개 이하로 제한 + DC balance (0/1 갯수 동일).
  • 1 bit 가 아닌 2 bit 추가 이유 — DC 균형 + K-Code (COM, SKP 등 제어 패턴) 공간 확보. 9 bit (512 조합) 으로는 256 데이터 모두에 대해 DC 균형이 수학적으로 불가.
  • 대가: 20% 대역폭 오버헤드.

128b/130b (Gen3+) — LFSR 스크램블링 방식:

  • 송수신 양쪽이 같은 LFSR 알고리즘으로 데이터를 무작위 섞음 (encoding table 폐기).
  • 무작위 섞인 데이터는 0 또는 1 이 길게 이어질 확률이 매우 낮아짐.
  • 추가된 2 bit 의 역할은 에러 검사 아님 — Sync Header: "이 128 bit 가 데이터인지 제어 명령인지" 구분.
  • 결과: 오버헤드 20% → 1.5%.
  • 가능해진 배경: 정밀해진 CDR + 강력한 EQ (Module 05 참조).

5.5 송신 흐름 — Memory Write 예 (전체)

위 §3 의 시나리오를 시간 축으로 다시:

Device CoreSender (TL/DLL/PL)Receiver (PL/DLL/TL) host PA 0x10000 에 64 B write 요청TL — MWr TLP 생성, FC credit 차감, ECRC 옵션DLL — Seq# + LCRC + Replay BufferPL — Framing + 128b/130b + scramble+ lane stripe → SerDeswirePL — CDR, decode, descramble, framing detectDLL — LCRC 검증 OK ACK DLLPTL — FC credit 반환, memory write 적용
Device CoreSender (TL/DLL/PL)Receiver (PL/DLL/TL) host PA 0x10000 에 64 B write 요청TL — MWr TLP 생성, FC credit 차감, ECRC 옵션DLL — Seq# + LCRC + Replay BufferPL — Framing + 128b/130b + scramble+ lane stripe → SerDeswirePL — CDR, decode, descramble, framing detectDLL — LCRC 검증 OK ACK DLLPTL — FC credit 반환, memory write 적용

5.6 수신 측 ACK/NAK 의 layer 분리

PL 가 깨진 비트 받음DLL 의 LCRC 검증 failDLL 이 NAK DLLP (with seq# = next expected) 전송PHY 통해 sender 로 가지만 PHY 가 만든 게 아님Sender DLL 이 NAK 받음Replay Buffer 에서 해당 Seq# 부터 다시 송신Replay 횟수 한도 초과→ DL_Inactive → LTSSM Recovery 진입
PL 가 깨진 비트 받음DLL 의 LCRC 검증 failDLL 이 NAK DLLP (with seq# = next expected) 전송PHY 통해 sender 로 가지만 PHY 가 만든 게 아님Sender DLL 이 NAK 받음Replay Buffer 에서 해당 Seq# 부터 다시 송신Replay 횟수 한도 초과→ DL_Inactive → LTSSM Recovery 진입

Layer 책임 분리의 가치: TLP (TL) 는 retransmit 을 신경 쓰지 않음. DLLLCRC 만 보고 packet 단위 reliability 만 처리. PHY 는 그저 bit 운반.

5.7 디버그 시 layer 추적

증상 의심 layer 확인
Link up 안 됨 PHY (LTSSM) LTSSM state, equalization 결과, electrical idle
Link up 했지만 packet 안 감 DLL DL_Active 진입 여부, FC init complete 여부
TLP 가 가지만 receiver 가 못 받음 DLL/TL LCRC error 율, Seq# wraparound, Replay 횟수
Specific TLP 만 fail TL Header field 오류 (Fmt/Type/Address), ECRC, ordering 위반
Latency 가 spike TL/DLL FC credit 부족, replay 발생 빈도
AER correctable error 카운터 ↑ DLL/PHY LCRC, replay number rollover, bad symbol

6. 흔한 오해 와 DV 디버그 체크리스트

흔한 오해

❓ 오해 1 — 'PCIe 의 reliability 는 PHY 가 책임진다 (BER 낮음)'

실제: Physical 은 raw bit 만 운반하며, packet-level reliability 는 Data Link Layer 의 ACK/NAK + sequence # + replay buffer 가 보장. PHYBER 이 아무리 낮아도 0 은 아니므로, 단일 비트 오류가 LCRC 에서 검출되면 DLL 이 재전송. 즉 PCIe 의 retransmission 은 DLL 의 일.
왜 헷갈리는가: 일반적으로 "신뢰성 = 물리 quality" 로 단순 연결 짓기 쉬움.

❓ 오해 2 — 'LCRCECRC 는 같은 CRC 다'

실제: 둘 다 32-bit CRC 지만 generator polynomial 이 다르고 범위/책임 이 다름. LCRC 는 hop 마다 새로 계산 (DLL 책임), ECRC 는 end-to-end (TL 책임, optional). Switch 가 TLP forward 할 때 LCRC 는 매 hop 새로 계산하지만 ECRC 는 그대로 둠 — 그래서 ECRC error 는 path 중간 어디선가의 corruption 을 잡아낸다.
왜 헷갈리는가: 둘 다 32-bit, 둘 다 TLP 위에 계산.

❓ 오해 3 — 'Memory Write 는 ACK 가 없으니 unreliable 하다'

실제: PCIe 의 MWr 은 TL-level Posted = TL 응답 없음. 그러나 DLLACK/NAK 은 발생 — receiver 의 DLL 이 packet 을 정상 받으면 ACK DLLP 가 sender 로 가고 Replay buffer 에서 해당 entry 가 retire. 따라서 link-level 신뢰성은 보장, 단지 application-level "내 write 가 정말 처리됐는가" 는 별도 확인 필요 (Module 03).
왜 헷갈리는가: "Posted" 와 "응답 없음" 을 link 전체로 해석.

❓ 오해 4 — 'TLP, DLLP 는 같은 channel 의 다른 이름이다'

실제: TLP 는 Transaction layer 의 packet, DLLP 는 Data Link layer 의 packet. PHY 위에서는 둘 다 byte stream 이지만 framing token 이 다름TLP 는 STP/END (Gen1/2) 또는 SDP-like (Gen3+), DLLP 는 별도 framing. Trace 도구가 layer 별 column 을 안 보여주면 ACK/NAK timing 추적 불가.

❓ 오해 5 — 'Layered 라서 layer 끼리 완전히 독립적이다'

실제: 송신 path 의 wrapper 는 layered 지만, 일부 정보는 layer 경계를 넘어 흐른다. 예: DLLFC DLLP 는 sender 의 TL 이 송신 가능 여부 판단에 사용. AERPHY/DLL 의 error 를 TL 의 capability 로 reporting. Layer 분리 = 책임 분리이지 정보 단절은 아님.

DV 디버그 체크리스트 (이 모듈 내용으로 마주칠 첫 실패들)

증상 1차 의심 어디 보나
Link 가 LTSSM L0 에 못 감 PHY (LTSSM stuck) LTSSM trace, Detect/Polling/Configuration 어디서 멈췄나 (Module 05)
L0 진입했지만 packet 0 DLL (DL_Inactive 또는 FC init 미완료) DL_Active 진입 여부, InitFC1/2 교환
LCRC error 카운트 증가 PHY BER 또는 DLL 송신 측 LCRC 계산 버그 AER correctable counter, replay 횟수
Specific TLPUR TL header field (Fmt/Type/Address) Packet trace, TL 의 routing 결과
Replay buffer overflow → recovery ACK 가 늦거나 NAK 빈발 DLL 양쪽의 ACK timer + LCRC error rate
Switch 통과한 TLPECRC fail path 중간 corruption switch 의 cut-through vs store-forward, 두 LCRC error 패턴
Gen 변경 시 packet drop LTSSM Recovery + DLL state 동시 처리 LTSSM trace 와 DLL state 동기화
AER correctable counter 가 천천히 증가 PHY BER 악화 trend EQ margin, replay 통계 (Module 07)

7. 핵심 정리 (Key Takeaways)

  • PCIeTransaction / Data Link / Physical 3 층 + 명확한 책임 분리.
  • 각 layer 의 packet 단위: TLP / DLLP / Ordered Set + Symbol.
  • Reliability 는 DLLACK/NAK + Sequence # + Replay Buffer 로 보장. PHYBER 은 별개 layer 의 문제.
  • 송신 path 는 layer 마다 wrapper 추가, 수신 path 는 역순 stripping.
  • Layer 분리 덕분에 디버그가 "증상 → layer → field" 의 직선적 흐름.

실무 주의점

  • "TLP" 와 "DLLP" 의 구분이 흐려지는 도구가 있음 — packet trace tool 에서 DLLP 를 별도 column 으로 보지 않으면 ACK/NAK timing 추적 불가.
  • LCRCECRC 를 혼동하지 말 것 — LCRC 는 hop, ECRC 는 end-to-end. 둘 다 32-bit CRC 지만 generator polynomial 이 다름.
  • Replay buffer 의 size 는 spec 가 아니라 implementation. 작으면 RTT 큰 link 에서 sender stall 발생 (credit 처럼).
  • Gen6 FLIT 모드에서는 layer boundary 가 살짝 변경됨 — TLP/DLLP 가 FLIT 안에 함께 들어가 ACK/NAK 메커니즘이 단순화. 자세한 건 Module 04.

7.1 자가 점검

🤔 Q1 — LCRC vs ECRC (Bloom: Analyze)

한 packet 의 LCRC 통과, ECRC fail. 어느 layer어떤 시나리오?

정답
  • LCRC 통과 → DLLlink integrity OK → wire 전송 자체는 무결.
  • ECRC fail → end-to-end 어딘가에서 data corruption:
    • Endpoint 의 TLP 생성 시 bug.
    • RC 또는 switch 가 routing 중 TLP payload 변경 (예: NAT-like).
    • Memory 의 ECC 처리 실패.

LCRC 만 보면 안전 같지만 ECRC 가 catch.

🤔 Q2 — Layer boundary 책임 (Bloom: Apply)

AER (Module 07) 가 correctable error 를 카운트. 어느 layer 의 어떤 error?

정답
  • Receiver Error: PHY layer (8b/10b encoding error, symbol error).
  • Bad TLP / Bad DLLP: DLL layer (LCRC error).
  • Replay Num Rollover / Timer Timeout: DLL.

모든 layer 가 자체 error counterAER 통합. 어느 layer 가 주된 error source 인지 즉시 분류.

7.2 출처

External - PCIe Specification 5.0/6.0 - PCI Express Technology — MindShare


다음 모듈

Module 03 — TLP: TL 의 packet (TLP) 의 header 필드, Fmt/Type 인코딩, P/NP/Cpl ordering, routing 3 가지.

퀴즈 풀어보기 →