前言
博主在第一篇5G相关文章[①5G NR]: 3GPP协议中Polar编码流程解读中介绍了Polar编码的相关流程,在本篇博客中就分享下LDPC(Low Density Parity Check)编码的相关流程。 因为LDPC码可以达到更高的译码吞吐量和更低的译码时延,所以可以更好适应高数据速率业务的传输,从而替代LTE中的Turbo码,成为5G中数据的编码方案,LDPC码将会用在PUSCH,PDSCH信道中,本篇博客主要参考38.212 3GPP协议章节5.2.2,5.3.2,5.4.2等。
LDPC参数
先介绍下LDPC码中需要用到的一些参数:
BG1 BG2 | Base Graph 1,2,基矩阵,LDPC中PCM(Parity-Check Matrix)扩展前的矩阵,是整个LDPC码设计的核心 |
rv_id | Redundancy Version,用于指示传输所使用的冗余版本,其取值范围为0~3,5G中的HARQ重传机制相关 |
N_l | MIMO的层数,取值范围1~4 |
Q_m | 符号携带比特数,取值1,2,4,6,8 |
N_cb | Circular Buffer 循环缓存的大小,5G通过循环缓存实现HARQ和速率匹配,将编码比特存储在循环缓存中,每次传输时根据冗余版本从循环缓存中顺序读取,实现速率匹配 |
B | 输入信息比特总长度 |
G | 输出总码长 |
LDPC编码流程
下面这张图总结了5G中LDPC的编码流程:
CB segmentation (码块分割)
k_cb | 每个CB所能携带的最大信息比特数,BG1为8448,BG2为3840 |
K’ | 每个码块携带的信息比特数(包含CRC) |
LDPC码接收到的是TB级的数据,在协议中定义了每个CB所能携带的最大信息比特数,BG1为8448,BG2为3840,所以当 B
≤
\leq
≤ k_cb 时,仅有一个码块需要进行编码,当 B
>
>
> k_cb 时,就需要进行码块的分割。如果进行码块分割,那么每个码块后面需要格外添加24位CRC校验,所以分割后一共有
c
e
i
l
[
B
/
(
ceil[B/(
ceil[B/(k_cb
−
24
)
]
- 24)]
−24)] 个码块。
CB CRC insertion (添加CRC)
如果进行码块分割,每个码块后面需要格外添加24位CRC校验比特,根据协议添加的是CRC24B。
Filler insertion (补filler比特0)
k_b | 临时参数, 针对短码字的特殊处理, BG1时无特殊处理, k_b = 22; BG2时, B > 640, k_b = 10;560 < B ≤ 640,k_b = 9; 192 < B ≤ 560,k_b = 8;B ≤ 192,k_b = 6 |
K | 每个码块携带的信息比特数(包括filler比特),BG1中,K = 22 * z_c;BG2中,K = 10 * z_c |
z_c | 扩展因子,基矩阵扩展中等用到,是在协议给出表中找到满足 z_c * k_b ≥ \geq ≥ K’ 的最小值 |
len_filler | 每个码块信息位中携带的filler比特数,filler比特全部设置为0,K - K’ |
在这个步骤就需要先计算z_c扩展因子了,z_c在LDPC码中可以被看作是一个重要的计量单位。它是先通过计算k_b,然后在协议给出的表中找到满足 z_c * k_b ≥ \geq ≥ K’ 的最小值:

找到z_c后就能根据协议给出的条件计算出包含filler比特的信息比特大小K,原来K’长度的信息比特就要在末尾补0,补齐K的长度。
LDPC encode (编码)
len_code | 编码后的码字长度,BG1中,68 * z_c,BG2中,52 * z_c |
len_parity | 编码添加的校验比特数,BG1中,46 * z_c,BG2中,42 * z_c |
5G中采用的是QC-LDPC码,通过Base Graph和z_c生成的校验矩阵计算码字,根据特殊的校验矩阵构成有快速算法,具体的编码算法可以参考博主[④5G NR]: 5G LDPC编码算法一文。因为是systematic的编码,LDPC编码后的结果并不是把原来的信息比特改的面目全非,而是在原来的信息比特后面接上新的校验比特数据:
Puncturing (打孔)
len_punc | 编码后,每个码字需要puncturing的比特数,2 * z_c |
len_info_punc | puncturing后,信息比特部分残留的比特数,K‘ - len_punc |
N | puncturing后码字长度,BG1中,66 * z_c,BG2中,50 * z_c,对应码率:BG1为1/3,BG2为1/5 |
LDPC码字起始的2 * z_c个比特,标准规定不进入循环缓存,即永远不会传输。所以在这步骤将 2 * z_c 个比特砍掉,称之为puncturing(打孔)。

Rate-matching (速率匹配)
C | 码块分割后,需要传输码字的个数,不做码块分割 C = 1 |
num_re | 临时参数, num_re = G / (N_l * Q_m) |
J | C个码字中前J个,J = C - num_re % C |
Er | bit-selection的比特数,对前J个码字,Er = N_l * Q_m * floor(num_re / C);对后C - J个码字,Er = N_l * Q_m * ceil(num_re / C) |
k0 | 比特选择时起始的比特位置,由rv_id,N_cb和协议中给出的表等确定 |
在速率匹配中分bit-selection(比特选择)和bit-interleaving(比特交织)两个步骤。
bit-selection
比特选择就是将原来打孔后N比特长度的码字映射成Er比特长度的码字,首先要确定比特选择的的起始位k0和Er的长度。k0跟N_cb和rv_id相关,在不开启LBRM的情况下N_cb = N,否则N_cb = min(N, N_ref),具体参考协议章节5.4.2.1:

确定了N_cb,再根据协议给出的表,就能确定k0的值:
在开头的表格中给出计算Er的公式,要注意的是如果做码块分割的话,前J个码块Er的长度跟后面码块Er的长度是不一样的,然后还要注意的是比特选择时,filler比特是不包含在内的,如果Er ≤ \leq ≤ len_info_punc + len_parity,就从原来N比特中从k0比特开始,跳过filler比特,依次选取Er个比特,如果Er > > > len_info_punc + len_parity,那不足的比特部分就要从k0开始循环的去选取。

bit-interleaving
比特交织跟Q_m的值相关,交织深度为Er / Q_m。举个例子,Q_m = 4,就是将比特选择后Er个比特分成四段,取每段第一个比特组成新序列的前四个比特,以此类推:

CB concatenation (码块联结)
如果做了码块分割的话,最后还需将各个码字的结果拼接起来作为最后G个比特的输出结果。