FEATURED · 精选文章

从汉明码到LDPC:差错控制编码原理与工程实践

发布时间 / 2026/9/12 3:50:03
来源 / 创域科博编辑部
栏目 / 资讯中心
从汉明码到LDPC:差错控制编码原理与工程实践 先问个问题如果信道是理想的我们还需要信道编码吗答案是不需要——但现实世界从来没有理想信道。无线信号穿过空气会被衰减、反射、多径干扰有线传输也躲不过热噪声和串扰。比特在信道上跑一圈总会有那么几个被翻转、丢失或者错位。差错控制编码也叫信道编码就是干这个的在发送端给信息比特有规律地加上冗余让接收端不仅能发现错误甚至能直接纠正错误。这篇文章写的是我在学习和实践“差错控制编码信道编码”时沉淀下来的笔记核心覆盖从最基础的奇偶校验、线性分组码、汉明码到工程里最常见的循环码与CRC再到卷积码、维特比译码、交织、级联码和现代Turbo/LDPC码的演进脉络。内容适合通信工程专业的学生、刚入行的基带算法工程师以及做嵌入式通信协议开发的朋友参考。我会尽量把原理讲得接地气同时把工程里真正会用到的参数、计算公式和踩过的坑一并写出来。1. 为什么通信系统离不开差错控制编码1.1 噪声与误码现实信道没有理想通道你可以在仿真里把信道设置为“无噪声”但一旦设备搬进实验室、放到室外事情立刻就变了。热噪声、冲击噪声、多径衰落、多普勒频移、邻频干扰……这些东西叠加在一起会以随机或突发的方式破坏比特。以无线通信为例一个符号经过调制后发射出去信道的传递函数不可能完全平坦接收端的信噪比SNR也不可能永远保持在理想值。当信噪比跌到某个门限以下判决器就会开始犯错误比特率BER直线上升。这里有一个粗浅但重要的直觉想要不增加发射功率、不改变调制阶数只靠“重新发一遍”来对抗误码在某些实时性要求高的业务里根本不可行。语音通话不能容忍你每错一帧就要求对方重说一遍视频直播更是不能为了一个错误包就无限缓冲。所以差错控制编码的思路是用“冗余换可靠性”——发送时故意多塞一些受控的校验信息让接收端能够通过冗余来发现甚至纠正错误。提示误码率指标不能只看平均BER很多工程场景真正关心的是“误帧率FER”或“误块率BLER”。信道编码方案的好坏最终要看它对BLER这条曲线的改善程度。1.2 差错控制编码在通信系统里的位置如果把一个通信系统拆开链路两端从信源到信宿一般会经过信源编码、加密、信道编码、调制、信道、解调、信道译码、解密、信源译码。信道编码紧挨着调制和解调它处理的对象是已经变成0/1序列的二进制数据。信道编码的输入是信息比特输出是经过规律性冗余扩展的编码比特接收端拿到经过信道污染的解调软信息或硬判决结果再做译码还原出最可能的信息比特序列。这里要引入一个概念叫“码率”Code Rate记作 R k/n表示每 n 个发送比特里有 k 个是真正有用的信息比特。R 越高冗余越少传输效率越高但纠错能力通常越弱R 越低冗余越多抗误码能力越强但带宽利用率下降。后面讲到的所有编码方案本质上都是在一个叫“香农限”的理论边界附近做权衡。2. 差错控制的基本方式和系统框架2.1 三种典型方式ARQ、FEC、HEC差错控制从系统层面看有三种实现方式我在实际项目里都接触过简单横向对比一下。ARQ自动重传请求接收端检测到错误后通过反馈信道请求发送端重传。这种方式实现简单适合误码率不高、时延不敏感的场景。典型例子是TCP的分组重传。缺点很明显反馈需要额外的信道资源重传会带来不可控的时延实时业务很难接受。另外在双向通信链路里如果反向信道质量也很差反馈本身也容易出错。FEC前向纠错发送端直接发送足够多的冗余接收端译码后自己纠错不需要反馈信道。典型例子包括汉明码、RS码、卷积码、Turbo码、LDPC码。FEC的优点是时延固定、单向可用非常适合广播、组播和实时流媒体。代价就是冗余占用带宽而且在信道极差时超过纠错能力的错误依然会漏过去。HEC混合纠错把ARQ和FEC结合常见做法是“轻量FEC ARQ”。先靠FEC纠正大部分错误剩下少部分无法纠正的再触发重传。这种方案在无线链路里很常见比如许多无线通信系统里物理层用FECMAC层或传输层再用ARQ兜底。工程上大家常说的“HARQ”混合自动重传请求就是HEC思想在标准里的落地形态它把重传的旧数据与当前传输的数据做软合并可以获得额外的分集增益。2.2 如何衡量信道编码的代价与收益衡量一种编码方案好不好要看几个维度编码增益Coding Gain在相同误码率条件下使用信道编码后所需信噪比相对于未编码系统的降低量。比如在BER10^-4时某卷积码能带来4dB增益意味着发射功率可以降低4dB这对终端续航和基站覆盖都有直接价值。复杂度译码算法的时间复杂度和空间复杂度。工程里经常遇到“理论增益1dB但硬件资源翻倍”的尴尬选择。时延编码块越大、交织越深时延越大。语音等实时业务对时延极其敏感不能为了增益无限增大编码块长度。误码平台Error Floor某些编码方案在高信噪比时误码率曲线不再陡降而是进入一个缓慢下降的平台区。这通常是由码字的最小距离分布太差或者译码器实现精度不够造成的。3. 线性分组码从奇偶校验到汉明码3.1 线性分组码的结构线性分组码是信道编码里最基础也最容易理解的一类码。所谓“分组”是指每次取出 k 个信息比特通过线性变换生成 n 个编码比特记为 (n,k) 码。“线性”的意思是任意两个合法码字相加结果仍然是合法码字模2加法。从数学上看编码过程可以写为c u × G其中 u 是 1×k 的信息向量G 是 k×n 的生成矩阵c 是 1×n 的码字。这里的加法和乘法都是模2运算也就是异或和与门逻辑。一个关键参数是最小汉明距离 d_min它决定了纠错能力可检测 e 个错误的条件d_min ≥ e 1可纠正 t 个错误的条件d_min ≥ 2t 1这个关系是所有分组码设计的基石。d_min 越大码的抗干扰能力越强但通常伴随着更多冗余。3.2 汉明码构造实例汉明码是线性分组码里最经典的例子最常见的 (7,4) 汉明码信息位 k4码长 n7最小距离 d_min3能够纠正任意1位错误检测2位错误。构造方式不复杂。设信息位为 u [u1 u2 u3 u4]生成矩阵可以写成系统码形式G [I4 | P]这里 I4 是 4×4 单位矩阵P 是 4×3 的校验位生成矩阵。编码后的码字前四位就是原始信息后三位是校验位。比如取P [[1,1,0], [1,0,1], [0,1,1], [1,1,1]]那么 c u × G得到的一个具体例子是u [1 0 1 1] 时计算校验位得到 c [1 0 1 1 | 0 0 1]。发送端就这样把7个比特送上信道。接收端要纠错需要用到校验矩阵 H。H 的构造满足 G × H^T 0。对于上面的 G(7,4)码的 H 通常是一个 3×7 矩阵。接收到 r 后计算伴随式s r × H^T如果 s 0说明 r 是合法码字大概率没错如果 s 非零根据 s 的值查表就能知道是哪个比特错了然后直接翻转纠正。这个“伴随式查表”的思路在后面看CRC时还会再见只是目标从纠错退回到了检错。3.3 伴随式译码与查表纠错伴随式译码的精髓是把“找出错误位置”变成“查一次预计算好的表格”。还是拿 (7,4)汉明码举例如果发送码字是 c信道把第5个比特翻转那么接收序列 r 与 c 只在第5位不同。此时 s r × H^T e × H^T其中 e 是错误图样只在第5位为1。因为 H 的每一列都是不同的非零模式所以 s 可以直接对应到具体的错误位置。我在工程实践里发现理解和手算一个(7,4)汉明码的完整过程比单纯背公式管用得多。从手算中你能真正体会到为什么 H 的列不能重复如果两列一样两种不同位置的错误就会对应同一个伴随式译码器分不清纠错就会出错。这个约束在所有线性分组码设计里都成立。注意汉明码虽然经典但实际工程中很少用它作为唯一的FEC方案因为它的码率不高R4/7≈0.57纠错能力也只有1比特。它更适合作为教材案例和入门理解工具。真正工程里常用的是后面讲的CRC做检错、卷积码或LDPC做纠错分工明确。4. 循环码与CRC工程中最常用的差错检测编码4.1 循环码的代数基础循环码是线性分组码的一个重要子类特点是一个码字任意循环移位后仍是合法码字。这个性质可以用多项式来统一描述把 n 位码字看成一个次数不超过 n-1 的二进制多项式例如 1011001 对应多项式 x^6 x^4 x^3 1。循环码的生成完全由一个生成多项式 g(x) 决定g(x) 是 x^n 1 的因式次数为 n-k。编码过程在多项式视角下非常简洁信息多项式 u(x) 乘以 x^(n-k)再用 g(x) 做模2多项式除法余数就是校验位。接收端校验同理把收到的多项式 r(x) 除以 g(x)如果余数为0说明 r(x) 是合法码字判定无误余数非零判定有错。工程里大家最常接触的循环码就是CRC循环冗余校验。它不用于纠错专门用于检错。因为它的检错能力非常强而且硬件实现极其简单所以在以太网、USB、Wi-Fi、存储系统里到处都是CRC的身影。4.2 CRC计算的通俗解释与移位寄存器实现CRC的计算表面上看是一堆多项式除法实际上硬件实现就是一个带反馈的移位寄存器。常见的CRC标准有标准多项式应用场景CRC-8x^8 x^2 x 1传感器数据帧、简单通信协议CRC-16-CCITTx^16 x^12 x^5 1Modbus、蓝牙、XMODEMCRC-32x^32 x^26 x^23 x^22 x^16 x^12 x^11 x^10 x^8 x^7 x^5 x^4 x^2 x 1以太网、ZIP、GZIP、PNG用多项式除法手算CRC的步骤可以这样记先在数据比特后面补 n-k 个0这个 n-k 等于生成多项式最高次数然后用生成多项式对延长后的比特序列做模2除法也就是异或运算不借位不进位最后得到的余数就是CRC校验值替换掉之前补的0即可。举个例子数据比特为 1101生成多项式为 1011对应 x^3 x 1最高次数3所以在数据后补3个0变成 1101000。用 1011 对 1101000 做模2除法得到余数001。最终发送的码字就是 1101 001。硬件实现时n-k 位的移位寄存器与生成多项式的非零系数位置接异或门。数据逐位移入后寄存器里留下的就是CRC值。这个过程没有除法器那种复杂的借位逻辑几个触发器和异或门就能跑得飞快这就是CRC能遍布各种高速接口的原因。5. 卷积码与维特比译码5.1 卷积码为什么适合连续比特流分组码一次处理一个固定长度分组信息比特之间没有跨越分组的记忆。卷积码不同它有一个约束长度 K 的概念当前输出不仅取决于当前输入比特还取决于之前 K-1 个输入比特。也就是说编码器是带状态寄存器记忆的有限状态机。一个典型的 (n,k,K) 卷积码k 表示每次输入比特数n 表示每次输出比特数码率 R k/n。以工程里常见的 (2,1,7) 卷积码为例码率1/2约束长度7编码器里有6级移位寄存器。每次输入1个比特输出2个比特。这两个输出比特是当前输入和寄存器历史比特的模2线性组合。不同组合方式由生成多项式决定比如最经典的133、171八进制生成多项式。卷积码的好处是它天然适合连续比特流的传输不需要等到一个完整分组到齐才开始编码。这对语音、视频这种实时连续数据非常友好。而且它的纠错性能相当不错配合维特比译码在中等码率和中等约束长度下能够提供接近最大似然译码的性能。5.2 维特比算法的核心思想维特比Viterbi算法是卷积码最常用的译码算法它解决的问题是给定一串接收序列找出最可能的发送路径。卷积码编码器从一个状态跳到另一个状态整个编码过程可以画成一张网格图Trellis。对于 (2,1,K) 卷积码状态数有 2^(K-1) 个每个状态每个时刻有两条入边和两条出边。维特比算法不枚举所有可能的发送序列而是在每个时刻对每个状态只保留一条“最可能到达该状态”的路径称为幸存路径。这样做之所以不丢最优解是因为网格图具有无记忆性质从当前时刻到未来路径的优劣只取决于当前状态到达同一个状态的不同历史路径里只有累计度量最小的那条值得保留。实际工程中维特比译码的度量常用汉明距离硬判决或欧氏距离软判决。软判决输入比硬判决通常能带来约2dB的增益所以现在接收机里做卷积码译码时几乎都会把解调器输出的软信息直接送给维特比译码器而不是先硬判决成0/1再译码。维特比算法还有一个工程细节叫“路径回溯深度”一般取约束长度的5到10倍。如果回溯深度太小路径还没收敛译码性能会下降太大则增加存储和时延。我在做FPGA实现时一般取 (2,1,7) 卷积码的回溯深度为35到42之间实测效果和理论性能已经很接近。6. 交织、级联码与现代编码演进6.1 交织把突发错误打散成随机错误信道产生的错误并不总是随机分布的。无线信道里的衰落、电力线信道里的脉冲干扰会导致一连串比特连续出错。这种“突发错误”对许多纠错码来说非常致命因为分组码和卷积码的纠错能力都是针对孤立错误设计的。交织技术的思路很简单发送前把编码后的比特顺序打乱接收端再按相反顺序恢复。这样即使信道里发生了一段连续错误经过解交织后错误比特会被分散到不同的码字、不同的位置变成“看起来像是随机错误”纠错码就能正常工作了。有两种常见交织方式块交织把编码比特按行写入一个矩阵再按列读出。接收端按列写入、按行读出。若矩阵有 R 行 C 列突发错误长度只要不超过 R就能保证每行只分到1个错误。卷积交织给每条支路增加不同的时延实现连续比特流的交织。比块交织时延更低适合实时业务。设计交织深度时需要同时考虑信道突发长度、纠错码纠错能力和业务时延预算。交织太浅起不到分散作用太深会引入无法接受的时延。我在做突发干扰测试时常常先用误码分布统计突发长度再反推需要的最小交织深度这样比拍脑袋定参数靠谱得多。6.2 级联码与Turbo码、LDPC码的简要脉络单个编码方案很难在所有维度同时做到最优于是就有了级联码的概念两个或多个编码器串起来用内码负责纠正大部分错误外码负责处理内码译码后残留的错误。最经典的级联结构是“外码RS 内码卷积码”曾经广泛用于深空通信和数字视频广播。RS码擅长纠正突发错误卷积码擅长纠正随机错误两者互补效果相当好。Turbo码的出现在1993年算是一次突破。它用两个卷积码编码器并行级联中间通过交织器把两份校验信息分开译码时两个译码器互相交换“外信息”经过多次迭代逼近最大似然性能。Turbo码在接近香农限的地方表现优异成为3G、4G移动通信里的主力编码方案。LDPC码则是另一条路线它的核心是一个“低密度”校验矩阵即矩阵里1的个数非常少。LDPC用置信传播Belief Propagation算法迭代译码在长码块、高码率场景下性能极好而且并行度高、实现开销可控。5G NR的数据信道就把LDPC定为主力编码控制信道仍然沿用Polar码。可以这么说现代通信的系统设计中“选哪种编码”已经变成“根据码长、码率、时延、吞吐和硬件复杂度寻找最佳折中”的问题。7. 工程中的实践心得与常见误区7.1 设计信道编码方案时最容易踩的坑我在实际项目里见过不少因为对编码理解不深而反复返工的情况整理几个典型第一只考虑编码增益不管时延和复杂度。有人在低时延业务里用了超长交织和超大LDPC码块结果理论增益是好看但端到端时延直接超标最后只能推倒重来。正确的做法是先梳理业务的时延预算再反推允许的最大编码块和交织深度。第二把CRC多项式选错。CRC虽然简单但多项式选得不好检错能力会明显下降。很多人直接网上抄一个多项式就用没注意数据长度、LSB/MSB顺序和初值设置。不同标准对初值、输入反射、输出异或的处理都不同代码里有一处不一致算出的CRC就和协议对不上。第三硬判决代替软判决。对卷积码和Turbo/LDPC码来说软判决信息能带来1.5到2.5dB的增益。有的项目为了简化设计直接用硬判决输入结果白白丢了好几个dB的性能后面为了提高覆盖又被迫增加发射功率非常不划算。第四漏测突发干扰。很多测试环境只加白噪声测出来的性能很好一到现场遇到变频器、电机火花、开关电源等产生的脉冲干扰错误就连串出现纠错码当场失效。做信道编码验证时一定要加入突发错误模型并配合交织器一起测试。7.2 常见问题速查表我整理了一份实际调试中经常要查的问题对照表遇到同类问题时可以直接按表排查。问题现象可能原因排查与解决译码后误码率不降反升发送端与接收端的生成多项式不一致核对编码器生成多项式、约束长度、码率是否完全一致CRC校验一直失败字节序或初值设置不对检查LSB/MSB反射设置和CRC初值用标准测试向量验证卷积码性能比理论差很多使用硬判决而未用软信息将解调器的对数似然比LLR直接送入维特比译码器突发干扰下性能崩溃没有加交织或交织深度不足根据实测突发长度增加交织深度并加入交织器做整链路测试LDPC译码在高信噪比出现平台迭代次数不足或量化精度不够增加最大迭代次数检查输入软信息的定点化比特宽度系统带宽利用率过低码率取得太低在满足BLER指标的前提下逐步提高码率用仿真找拐点提示信道编码是一项需要“整链路思维”的技术任何一个环节不匹配都会把编码增益吃掉大半。建议在项目早期就搭一套端到端的仿真环境包含编码、调制、信道、解调、译码所有参数可配置。这样调试一个参数的影响时你能立刻看到全链路效果而不是在孤立模块里反复猜测。最后分享一点个人习惯我做了这么多年通信底层有一个习惯一直保留拿到任何新的编码方案先不用仿真工具而是手工算一个最短码字的完整编码和译码过程。比如用笔算一个(7,4)汉明码或者把一条卷积码的网格图画三五个时刻。这个过程看着慢实际上能逼你把生成矩阵、校验矩阵、状态转移、伴随式这些概念全部过一遍很多后面才暴露的bug在手工计算阶段就能提前暴露。编码理论的公式并不难难的是把“线性、冗余、状态、度量”这些概念真正串起来。等你亲手算通一次再去看FPGA代码或DSP代码会明显感觉心里有底得多。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻