首页 › ran › 5G HARQ-ACK码本与DAI机制拆解

5G HARQ-ACK 码本与 DAI 机制全链拆解:从漏检恢复到动态码本构造

一、问题起点:为什么需要"码本"这个东西

在 LTE 时代,HARQ 反馈相对直接:基站每发一个下行传输块(TB),终端就在固定的时序位置回一个 ACK/NACK。但 5G NR 把这套规则打碎了——因为 NR 同时引入了灵活 K1 反馈时序、载波聚合(CA)多服务小区、一个 PUCCH 反馈多个 PDSCH、多时隙调度等特性。

这带来了一个致命问题:当终端漏检了某个 DCI(即没有收到某个 PDSCH 的调度授权),它就不知道这一轮本该反馈多少个 ACK/NACK,也不知道基站期望的反馈在 PUCCH 上的比特位置。位置一错,整个反馈窗口全乱:基站把 NACK 误读成 ACK,重传不再触发,数据静默丢失。

为了解决"终端与基站对反馈位置的认知必须严格对齐"这一核心矛盾,3GPP 在 TS 38.213 第 9 章定义了 HARQ-ACK codebook(码本) 机制,并在 TS 38.212 的 DCI 格式中嵌入了 DAI(Downlink Assignment Index,下行分配索引) 字段。这两者是一对孪生设计:码本规定反馈结构,DAI 保证在动态结构下终端能"补齐漏检"。

本文聚焦 TS 38.213 §9.1 系列,把这条链路从 K1 时序、三种码本类型、DAI 计数原理、Type-2 构造算法、到 PUCCH 承载与 UCI 复用,逐层拆解。

二、前置:HARQ 反馈时序 K1

一切码本讨论都建立在 K1(PDSCH-to-HARQ-ACK timing) 之上。K1 定义的是:PDSCH 所在的时隙 n,其 HARQ-ACK 反馈在 n + K1 个上行时隙发送。

这个设计的关键在于:不同 PDSCH 可以指向同一个 PUCCH 反馈时隙。比如时隙 n 的两个 PDSCH 分别用 K1=4 和 K1=3 指向同一个上行时隙 n+4。于是"一个 PUCCH 携带多个 PDSCH 的反馈"成为常态——这正是码本要解决的问题。

sequenceDiagram
    autonumber
    participant gNB
    participant UE
    Note over gNB,UE: 一个 PUCCH 反馈时隙承载多个 PDSCH 的反馈
    gNB->>UE: DCI 1_1 (PDSCH#A, K1=3)
    gNB->>UE: PDSCH#A @ slot n
    gNB->>UE: DCI 1_1 (PDSCH#B, K1=4)
    gNB->>UE: PDSCH#B @ slot n+1
    gNB->>UE: DCI 1_1 (PDSCH#C, K1=2)
    gNB->>UE: PDSCH#C @ slot n+2
    Note over UE: 三者 K1 指向同一反馈时隙 n+4
    UE->>gNB: PUCCH (slot n+4) 携带 [ACK_A, NACK_B, ACK_C] 码本

理解了 K1 是"汇聚器",码本就是"被汇聚的比特集合的排列规则"。

三、三种码本类型:半静态、动态、一次性

3GPP 定义了三种 HARQ-ACK codebook,对应三种不同的"反馈排列哲学":

1. Type 1 — 半静态码本(Semi-Static,§9.1.2)

由 RRC 参数 pdsch-HARQ-ACK-Codebook = semiStatic 触发。码本大小与实际调度无关,预先固定。

构造逻辑:终端根据 RRC 配置的 K1 集合、PDCCH 监听时机(MO)集合、服务小区集合,预先枚举出一个"候选 PDSCH 接收时机"的二维/三维网格 M。无论基站实际是否在这些位置调度了 PDSCH,码本里每一个位置都占一格:

优点:结构完全可预测,终端和基站永远对齐,完全不需要 DAI(DAI 在 Type 1 中仅作冗余校验)。 缺点:开销大。当基站实际只在网格里调度了少量 PDSCH 时,码本里塞满了无意义的 NACK 占位比特,浪费 PUCCH 容量。

2. Type 2 — 动态码本(Dynamic,§9.1.3)

由 pdsch-HARQ-ACK-Codebook = dynamic 触发。码本大小根据实际收到的 DCI 动态确定,DAI 是其核心。

终端不再枚举固定网格,而是只对实际检测到下行分配的 DCI 进行 ACK/NACK 排列。由于结构是动态的,必须有 DAI 来告诉终端"你这一轮总共该收到几个、当前是第几个",否则漏检一处就会错位。

优点:开销最小,只反馈实际调度。 缺点:逻辑复杂,依赖 DAI 的正确计数与漏检恢复。

3. Type 3 — 一次性码本(One-shot,R16,§9.1.4)

Rel-16 引入。一次性反馈一个或多个 HARQ 进程的当前 ACK/NACK 状态,与是否被本次调度无关。

由 DCI 中的 "HARQ-ACK request (one-shot)"(或 DCI 1_2 的对应字段)触发。用于 eMIMO、multi-TRP、URLLC 等场景下,长时间未反馈导致 gNB 与 UE 的 HARQ 进程状态失步后,强制同步一次。

三种码本的对比如下表:

维度 Type 1 半静态 Type 2 动态 Type 3 一次性
引入版本 R15 R15 R16
TS 38.213 章节 §9.1.2 §9.1.3 §9.1.4
RRC 触发参数 pdsch-HARQ-ACK-Codebook=semiStatic =dynamic DCI one-shot 字段触发
码本大小 固定(RRC 预计算) 动态(随调度变化) 固定(=HARQ 进程数)
是否依赖 DAI 否(仅冗余校验) 是(核心) 否
漏检 DCI 处理 天然占位 NACK DAI 补齐 NACK 反馈进程当前状态
开销 高 低 中(一次性)
典型场景 调度密集、稳定 CA、稀疏调度 multi-TRP、URLLC、状态同步

四、DAI 深度解析:Counter DAI 与 Total DAI

DAI 不是单一字段,而是两个子字段的组合,这是初学者最容易混淆的点。

Counter DAI(C-DAI)

累计计数器:到当前 PDCCH 监听时机为止,基站已经下发(含当前这条)的下行分配的累计序号。计数顺序为:先按服务小区(carrier)递增,再按 PDCCH 监听时机(MO)递增。

例如:PCell 上调度 → C-DAI=1,SCell#1 调度 → C-DAI=2,SCell#2 调度 → C-DAI=3,下一个 MO 的 PCell → C-DAI=4……以此类推,模 4 循环(0→1→2→3→0)。

Total DAI(T-DAI)

总数指示:到当前 PDCCH 监听时机为止,跨所有服务小区,本轮(将复用到同一个 PUCCH)下行分配的总数。同样模 4。

T-DAI 的价值在于"封口":它告诉终端"这一捆里一共有多少个分配",使终端能在最后一个监听时机就确定码本的总大小。

DAI 字段在 DCI 中的承载(TS 38.212)

DCI 格式 Counter DAI Total DAI 比特数 说明
DCI 1_0 有(2 bit) 无 2 仅 counter,常用于回退调度
DCI 1_1 有(2 bit) 有(2 bit) 2 + 2 counter + total,Type-2 主力
DCI 1_2 (R17) 有 有 可变 更紧凑,适配 NR-Light

两个 DAI 都是 2 bit、模 4 计数。模 4 的设计是一个精妙折衷:4 个值(0/1/2/3)能在 2 bit 内表达,覆盖一轮 4 个分配的循环;当一轮分配数超过 4 时靠多轮循环 + T-DAI 配合还原。

DAI 漏检恢复原理(核心机制)

这是整个机制的灵魂。设想一个 CA 场景,本轮 5 个下行分配:

事件 C-DAI T-DAI UE 是否收到
分配1(PCell) 1 5 ✅ 收到
分配2(SCell1) 2 5 ❌ 漏检
分配3(SCell2) 3 5 ✅ 收到
分配4(SCell3) 4 5 ✅ 收到
分配5(PCell) 1(模4) 5 ✅ 收到

UE 的恢复逻辑(对应 TS 38.213 §9.1.3.2 伪代码):

  1. C-DAI 跳变检测:UE 收到的 C-DAI 序列是 1 → (缺2) → 3 → 4 → 1。当 UE 发现 C-DAI 从 1 直接跳到 3(增量不是 +1),判定 C-DAI=2 的位置发生了漏检,在该位置插入一个 NACK 占位。
  2. T-DAI 封口校验:最后收到的 T-DAI=5,说明本轮总数应为 5。UE 用 T-DAI 锁定码本总长度为 5,确保后续 PDSCH(如多 MO 跨度)的对齐。
  3. 码本对齐:UE 最终构造 [#1=ACK, #2=NACK(补), #3=NACK, #4=ACK, #5=ACK],与基站期望的 5 比特位置完全对齐。

如果连携带 T-DAI 的最后一个 DCI 也漏检了怎么办? 此时 UE 无法得到总数,使用最后一个正确接收的 T-DAI 值作为码本大小上界——这是一种尽力而为的降级,保证不会比真实值少,至多多补 NACK。

五、Type 2 动态码本构造流程

将上述原理形式化为流程:

flowchart TD
    A[UE 在 PDCCH 监听时机检测到下行分配] --> B{是否携带 C-DAI / T-DAI?}
    B -- 是 --> C[记录 C-DAI 当前值]
    B -- 否 --> Z[忽略, 非 Type-2 调度]
    C --> D{C-DAI 增量是否等于 +1?}
    D -- 否 --> E[检测到跳变 → 判定漏检]
    E --> F[在缺失位置插入 NACK 占位比特]
    D -- 是 --> G[按序追加该 PDSCH 的 ACK/NACK]
    F --> G
    G --> H{是否还有后续监听时机?}
    H -- 是 --> A
    H -- 否 --> I[取最后一个有效 T-DAI 作为码本总数 N]
    I --> J{UE 实际收集到的 C-DAI 最大值<br/>是否 < T-DAI?}
    J -- 是 --> K[尾部补 NACK 至 N 比特]
    J -- 否 --> L[码本长度对齐完成]
    K --> L
    L --> M[码本输出: N 个 HARQ-ACK 比特]
    M --> N2[映射到 PUCCH 资源传输]

这个流程揭示了 Type-2 的三道对齐防线:C-DAI 防中间漏检、T-DAI 防尾部漏检、模 4 循环防计数溢出。

六、码本类型选择决策与承载

码本类型本身不是终端自选的,而是 RRC 配置 + DCI 触发的组合决策:

flowchart TD
    S[RRC: pdsch-HARQ-ACK-Codebook 配置] --> T{配置值}
    T -- semiStatic --> T1[Type 1: 固定网格<br/>枚举 K1 × MO × Cell]
    T -- dynamic --> T2[Type 2: 动态结构<br/>依赖 DAI 计数]
    T2 --> DCIcheck{DCI 是否带 one-shot<br/>HARQ-ACK request?}
    DCIcheck -- 是 --> T3[Type 3: 一次性<br/>反馈所有 HARQ 进程状态]
    DCIcheck -- 否 --> T2f[保持 Type 2 动态码本]
    T1 --> Sel[确定码本比特序列]
    T2f --> Sel
    T3 --> Sel
    Sel --> PUCCH[PUCCH Format 选择<br/>1~2bit→F0/F1<br/>多bit码本→F2]
    PUCCH --> Tx[上行传输]

注意一个细节:Type 1 与 Type 3 的码本大小都依赖 RRC 配置(Type 1 依赖 K1 候选集,Type 3 依赖 HARQ 进程数),唯独 Type 2 是真正运行时动态的。这也是为什么 DAI 机制只在 Type 2 中是"必需"的。

码本如何映射到 PUCCH

码本生成后,需要选择 PUCCH 资源承载。承载能力由 PUCCH 格式决定:

PUCCH 格式 承载 UCI 比特 时长 典型用途
Format 0 1–2(HARQ-ACK/SR) short/long 单或少比特反馈
Format 1 ≤2 short/long HARQ-ACK + SR(序列扩频)
Format 2 >2 short/long 码本较大时的主力
Format 3 ≤1150 short/long 大 UCI(CSI + 码本)
Format 4 ≤1150 + OCC short only 大 UCI + 正交复用

经验法则:HARQ-ACK 比特少时用 Format 0/1;当 Type-2 码本因 CA 或多时隙调度膨胀到数比特以上,自动切换到 Format 2。

七、UCI 复用与空域捆绑

UCI 复用优先级(§9.2)

当 HARQ-ACK、SR(调度请求)、CSI 需要在同一上行时机反馈时,存在复用与丢弃规则:

空域捆绑(Spatial Bundling)

当一个 PDSCH 携带 2 个码字(TB)时,默认需要反馈 2 个 HARQ-ACK 比特。若开启 harq-ACK-SpatialBundlingPUCCH,则对两个码字的反馈做逻辑 AND,仅反馈 1 比特——两个码字都正确才回 ACK,否则 NACK。这是一种用可靠性换开销的折衷。

八、Rel-16/17/18/19 演进脉络

DAI 与码本机制并非一成不变,每个版本都在打补丁与扩边界:

这条演进线说明:HARQ-ACK 码本始终是 5G 物理层"可靠性 ↔ 开销 ↔ 时延"三角博弈的核心调节器。

九、实战连接:抓包识别与故障排查

抓包识别要点

在 Wireshark/TShark 中分析 5G L1/L2 抓包(如 gNB 内部信令跟踪、或 O-RAN CU/DU 接口抓取),识别 HARQ-ACK 链路:

  1. 定位 DCI:在 PDCCH 解码中找到 DCI 1_1,检查 "Downlink assignment index" 字段值,确认 counter/total DAI 的递进。
  2. 关联 PDSCH:通过 RNTI(C-RNTI)和 HARQ Process ID 把 DCI 与对应 PDSCH 配对。
  3. 验证 K1:确认 PDSCH slot + K1 = PUCCH slot,检查 DCI 的 "PDSCH-to-HARQ_feedback timing indicator" 字段是否落在 RRC 配置的候选集内。
  4. 解码码本:在 PUCCH 解码中提取 HARQ-ACK 比特串,按 Type-1/2 规则反推每个比特对应的 PDSCH。
  5. DAI 一致性检查:人工核对终端上报的码本长度是否等于最后一个 T-DAI;不等则怀疑漏检或实现 Bug。

常见故障点

常见问题

Q1: Type 1 和 Type 2 到底该用哪个? A: 看调度密度与 CA 程度。调度稳定、密集、CA 较少 → Type 1(实现简单、鲁棒,且此时占位开销可接受);CA 多、调度稀疏/突发、PUCCH 资源紧张 → Type 2(开销小)。Type 2 是 5G 的主流选择,但 Type 1 在特殊场景仍有价值。

Q2: 为什么 DAI 只有 2 bit、还要模 4? A: 2 bit 是开销与表达力的折衷。模 4 循环配合 T-DAI 的总数指示,即使一轮分配超过 4 个也能正确还原。理论上若用更多 bit(如 LTE TDD 的 4 bit),开销翻倍而收益有限,因为 T-DAI 已提供总数封口。

Q3: 如果终端连最后一个带 T-DAI 的 DCI 都漏检了怎么办? A: 终端使用最后一个正确接收到的 T-DAI 值作为码本大小上界(TS 38.213 §9.1.3 降级规则)。这是尽力而为——码本不会比真实值小(不会丢比特),至多多补几个 NACK 占位,基站据此重传,最终仍能收敛正确。

Q4: DAI 和 HARQ Process ID 是一回事吗? A: 完全不同。HARQ Process ID(DCI 中 3-4 bit,R19 扩展支持 32 进程)标识的是软缓冲区编号,用于合并重传;DAI 标识的是本轮码本内的反馈序号,用于对齐反馈位置。一个码本里多个比特可对应不同 HARQ 进程,两者正交。

Q5: Type 3 一次性码本什么时候触发? A: 由 DCI 1_1/1_2 的 one-shot HARQ-ACK request 字段显式触发。典型用于 multi-TRP 切换、URLLC 高可靠场景,或长期未反馈导致 gNB/UE 进程状态可能失步时,强制同步所有 HARQ 进程的当前 ACK/NACK 状态。

参考来源

  1. 3GPP TS 38.213 V19.x.x — NR; Physical layer procedures for data — §9.1 HARQ-ACK 传输时序、§9.1.2 Type 1 码本、§9.1.3 Type 2 码本、§9.1.4 Type 3 码本
  2. 3GPP TS 38.212 — NR; Multiplexing and channel coding — DCI format 1_0/1_1/1_2 中 Counter DAI / Total DAI 字段定义
  3. ShareTechnote — 5G/NR HARQ-ACK Codebook — 码本构造图解与举例
  4. 3GPP Explorer — DAI (Downlink Assignment Index) Glossary — DAI 机制原理与 Rel-15~19 变更记录(CR 列表)
  5. CafeTele — HARQ in 5G NR: Process, Codebook — 16 进程、NDI、K1/K2、半静态 vs 动态码本总结

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入