卷积码原理与应用:从维特比算法到5G通信的纠错技术
1. 从“乱码”到“纠错”一个通信工程师的日常困惑如果你曾经在信号不好的地方打电话听到过断断续续或夹杂着杂音的声音或者在网络波动时看到视频画面出现马赛克那么你已经直观地体验到了数字通信中的核心挑战如何在充满噪声和干扰的信道中可靠地传输信息作为一名在通信领域摸爬滚打了十多年的工程师我处理过无数次因传输错误导致的系统告警。早期我们最朴素的想法就是“重复发送”。比如要发送一个比特“1”为了防止出错我们连续发送三次“111”。接收端收到“101”时通过“少数服从多数”的规则就能判断出原始信息很可能是“1”。这种方法简单粗暴就是重复码。但它有个致命缺点效率极低。为了纠正一个可能的错误我需要额外发送两倍的数据带宽利用率直接打了三折。在频谱资源寸土寸金的今天这无疑是巨大的浪费。那么有没有一种方法既能像重复码一样拥有强大的纠错能力又不会过分牺牲传输效率呢这就是信道编码特别是卷积码登场的舞台。我第一次接触卷积码的理论时也被那些状态图、网格图、维特比算法搞得一头雾水觉得它高深莫测。但后来在实际的无线模块调试、卫星数传系统设计中反复使用后我发现它的核心思想其实非常直观和巧妙远没有公式看起来那么吓人。简单来说卷积码是一种“记忆”的编码。它不会像重复码那样呆呆地复制当前信息而是会让当前要发送的比特与之前已经发送过的几个比特“聊聊天”共同商量出一个更靠谱的“对外发言稿”。这个“聊天”的过程就是卷积运算而“聊天的对象范围”即记忆长度就是约束长度。正是这份“记忆”让卷积码拥有了从看似杂乱的接收序列中推断出最有可能的原始信息序列的能力其纠错性能远超简单的重复码而编码效率有用信息比特数/总发送比特数却可以做得非常高比如常见的1/2、2/3、3/4码率。今天我就抛开那些复杂的数学推导用最贴近工程师思维的方式带你彻底搞懂卷积码到底是怎么“想”的以及它如何在诸如你的手机4G/5G信号、Wi-Fi、深空通信比如火星探测器传回照片等场景中默默守护着每一个比特的安全。你会发现理解它之后再看那些通信协议手册里的相关章节会清晰得多。2. 核心思想拆解当比特有了“朋友圈”要理解卷积码关键在于抓住三个核心概念编码器、状态和记忆。我们可以用一个非常生活化的类比来建立直觉。2.1 编码器一个简单的“信息加工车间”想象一个微型工厂编码器它每次接收一个新鲜的信息比特比如0或1。但这个工厂不是单独处理这个新比特它有一个小小的“记忆车间”里面存放着之前处理过的两个比特。我们假设这个记忆车间只有两个存储单元寄存器分别记为M1和M2。初始时M1和M2都清零存0。现在流水线开始工作一个新的信息比特u到达。这个新比特u会被送入记忆车间它存入M1而原来M1里的比特则被推到M2里原来M2里的最老的比特就被“挤出去”丢弃了。这个过程就像是一个移位寄存器。此时车间里共有三个相关的比特新来的u现在在M1、上一个比特现在在M2、以及上上个比特刚被丢弃但我们可以认为它曾影响过M2的旧值不过在这个简化模型里我们先关注当前存着的两个。现在这个工厂要输出产品了即编码后的比特称为“码字”。它不止输出一个比特而是输出两个比特(c1, c2)这样编码效率就是 1/2输入1比特输出2比特。这两个输出比特怎么来呢它们是由当前车间里的比特通过固定的“加工规则”生成多项式计算出来的。例如我们定义两条加工流水线流水线A生成c1c1 u ⊕ M2⊕表示异或运算相同为0不同为1流水线B生成c2c2 u ⊕ M1 ⊕ M2为什么是异或因为异或运算在二进制域里是最基本的线性运算硬件上用一个简单的“异或门”就能实现速度快、成本低。而且这种线性组合为后续的数学分析和解码提供了巨大的便利。我们来模拟一下这个过程。假设要发送的信息序列是1101。初始M10, M20输入u1M1新存入1M2存入原M1的0。此时(M1, M2) (1, 0)。计算输出c1 u⊕M2 1⊕0 1c2 u⊕M1⊕M2 1⊕1⊕0 0。输出码字(1,0)。同时记忆状态更新为(1,0)。输入u1新比特1进入M1原M1的1进入M2。此时(M1, M2) (1, 1)。计算c1 1⊕1 0c2 1⊕1⊕1 1。输出码字(0,1)。状态更新为(1,1)。输入u0新比特0进入M1原M1的1进入M2。此时(M1, M2) (0, 1)。计算c1 0⊕1 1c2 0⊕0⊕1 1。输出码字(1,1)。状态更新为(0,1)。输入u1新比特1进入M1原M1的0进入M2。此时(M1, M2) (1, 0)。计算c1 1⊕0 1c2 1⊕1⊕0 0。输出码字(1,0)。最终对于信息序列1101我们得到的编码输出序列是(10), (01), (11), (10)串联起来就是10011110。看仅仅4个信息比特因为编码器的“记忆”产生的8个编码比特之间存在着强烈的相关性。这种相关性正是纠错能力的来源。2.2 状态编码器的“瞬时记忆快照”上面例子中(M1, M2)这个二元组比如(1,0)、(1,1)、(0,1)就称为编码器的状态。因为M1和M2各能存0或1所以总共有 2^2 4 种可能的状态00,01,10,11。状态完整地描述了编码器在某一时刻的“记忆内容”它决定了下一个输入比特会如何被加工以及编码器会跳转到哪个新的状态。这引出了一个极其重要的工具——状态转移图。它把编码过程看作一个状态机在不同状态间的跳转。状态图以文字描述 我们有四个状态节点S0(00), S1(01), S2(10), S3(11)。 每条有向边表示一次输入和对应的输出。 例如从状态 S0(00) 开始 - 如果输入 u0新状态仍是 (00)因为0进入M1原M1的0进入M2输出 (c1,c2) (0⊕0, 0⊕0⊕0) (0,0)。所以有一条从S0到S0的边标为 “0/00”。 - 如果输入 u1新状态变为 (10)1进入M10进入M2输出 (1⊕0, 1⊕0⊕0) (1,1)。所以有一条从S0到S2的边标为 “1/11”。 同理我们可以画出所有状态在所有可能输入下的转移边。这个图之所以强大是因为它将时间上连续的编码过程转化为了空间上清晰的状态路径。发送端编码的过程就是沿着某条路径由输入比特序列决定在状态图中游走并输出边上标注的码字。而接收端解码的任务恰恰相反我收到一串可能出错的码字序列要在所有可能的状态路径中找出哪一条路径产生的输出序列与我的接收序列最“像”。2.3 网格图把状态图按时间展开状态图是静态的而通信是一个持续的过程。为了分析一个序列我们引入网格图——将状态图按时间顺序展开。横轴是时间刻度每个输入比特的时刻纵轴是所有可能的状态。这样任何一条信息序列都对应网格图中从起点开始的一条唯一路径。假设我们从状态00开始发送两个比特。网格图的前两节如下所示用文字描述其结构时刻0我们位于状态00。时刻1输入第一个比特如果输入0沿“0/00”边走到达状态00。如果输入1沿“1/11”边走到达状态10。时刻2输入第二个比特从状态00出发输入0走到00边“0/00”输入1走到10边“1/11”。从状态10出发输入0走到01计算新状态(0,1)输出(0⊕1,0⊕0⊕1)(1,1)这里需要根据生成多项式精确计算我们暂不深究具体值理解概念即可输入1走到11。注意这里的关键不是记住每条边的具体输出值而是理解网格图定义了所有可能的编码路径。一条信息序列对应一条路径路径上所有边的输出连起来就是最终的编码序列。当信道引入错误接收序列会偏离任何一条合法路径。解码器的任务就是在网格图的“路径丛林”中找到那条与接收序列“距离最近”的合法路径。这个“距离”通常用汉明距离对应比特不同的个数或欧氏距离对于软判决来衡量。3. 维特比算法在“路径丛林”中寻找最优解现在到了最精彩的部分解码。接收端拿到一串可能包含错误的序列比如我们发送了10011110但信道干扰导致第三个比特出错收到了10111110下划线标出错误位。我们如何从这串序列反推出最有可能的原始信息1101呢最笨的方法是穷举列出所有可能的信息序列对于4个比特有16种可能分别用编码器模拟编码得到16条候选编码序列然后逐一与接收序列10111110比较看哪条序列的汉明距离最小即不同的比特数最少。对于4个比特这可行但如果发送1000个比特呢候选路径有2^1000条这是天文数字无法计算。维特比算法的天才之处在于它利用网格图的特性和“最优路径原理”将指数复杂度降低为线性复杂度。它的核心思想是在网格图中到达某一时刻某个状态的最优路径必然是由到达前一时刻某个状态的最优路径延伸而来的。我们来模拟一下维特比算法对接收序列10111110的解码过程。为了简化我们假设一个更短的例子并聚焦于算法流程。假设我们使用前述的(2,1,3)卷积码约束长度3记忆单元2从全零状态开始并假设结束时也归零通过添加尾比特。算法步骤初始化在时刻0只有状态00是可能的其累积路径度量距离设为0。递推核心对于每一个时刻t从1开始对于当前时刻的每一个可能状态s找出在时刻t-1能转移到状态s的所有前驱状态。对每一个前驱状态s计算从s到s这条分支的度量即接收到的该时刻的2个比特与这条转移边理论上应输出的2个比特之间的汉明距离。将s的累积路径度量加上这个分支度量得到一个候选的到达s的路径度量。比较所有能到达s的候选路径度量选择最小的那个值作为状态s在时刻t的新的累积路径度量并记录下这条最优路径是从哪个前驱状态s来的幸存路径。这个“比较-选择-记录”的过程称为“加-比-选”。路径回溯当处理完所有接收数据包括尾比特使得状态归零后在最终时刻比如归零后的时刻选择累积路径度量最小的那个状态应该是00。从这个状态开始沿着之前记录的“从哪个前驱状态来”的信息反向回溯就能找出整个时间跨度上的最优路径。这条路径对应的输入比特序列就是解码出的信息。为什么它能大大降低复杂度因为在每个时刻对于每个状态我们只保留了一条最优的“幸存路径”而丢弃了其他较差的路径。随着时间推进需要存储和计算的路径数量是固定的等于状态数如4条而不会像穷举法那样指数增长。无论发送1000比特还是10000比特解码器在每个时刻都只进行固定次数的“加-比-选”操作。实操心得软判决与硬判决上面我们用汉明距离比特对比特比较这叫硬判决解码接收端先对模拟信号进行判决得到0或1的硬比特再交给维特比算法。但这样会丢失信息。更优的方法是软判决解码接收端不急于判决成0或1而是将解调后的模拟信号量化为多个电平如8级直接将这些“软信息”比如0.9表示很可能是00.1表示很可能是1输入维特比算法。算法在计算分支度量时使用欧氏距离或其他更适合软信息的度量。软判决能比硬判决带来约2-3dB的编码增益这在低信噪比环境下是至关重要的性能提升。在实际的芯片如DSP、FPGA实现中是否支持软判决以及软判决的量化比特数是衡量一个解码模块性能的关键指标。4. 关键参数与性能权衡工程师的选型指南在实际项目中我们不会从头设计一个卷积码而是从标准中选取或根据系统需求确定参数。理解这几个参数的含义和权衡是正确应用卷积码的前提。4.1 约束长度 (K)这是卷积码最重要的参数之一它定义了编码器的“记忆深度”。更准确地说约束长度 K 表示当前输出比特受多少个输入比特的影响。在我们之前的例子中记忆单元寄存器有2个M1,M2但当前输入比特u本身也算一个所以约束长度 K 3。通常K 越大编码器的记忆越长产生的码字间约束关系越复杂纠错能力潜在越强。因为一个错误比特需要“欺骗”更长一串相关的校验比特才能不被发现。但是K 增大带来的代价是解码复杂度急剧上升。维特比算法的状态数是 2^(K-1)。当 K3 时状态数4K5 时状态数16K7 时状态数64K9 时状态数256。状态数翻倍意味着维特比解码器在每个时刻需要进行的“加-比-选”操作次数、需要存储的幸存路径信息量都几乎成倍增长。在硬件实现中这直接转化为更多的逻辑门、更大的存储器和更高的功耗。经验之谈在卫星通信等对可靠性要求极高、且功耗和体积限制相对宽松的场景常采用 K7 甚至 K9 的卷积码。而在早期的2G GSM手机中使用的是 K5 的卷积码在性能和复杂度间取得了良好平衡。对于很多嵌入式系统K3 或 K4 的“轻量级”卷积码仍然被广泛用于内部链路或对时延敏感的控制信道。4.2 码率 (R)码率 R k / n表示每输入 k 个信息比特输出 n 个编码比特。我们例子中是 1/2 码率。码率直接衡量了编码的效率。R 越高如 3/4, 7/8效率越高但纠错能力通常越弱因为用于校验的冗余比特比例变少了。R 越低如 1/3, 1/4冗余度越高纠错能力越强但带宽效率也越低。工程上我们常常通过凿孔技术来从一个低码率母码如1/2码生成高码率码。例如一个1/2码的输出序列是c1, c2, c3, c4, c5, c6, ...。如果我们按照一个固定的图案删除凿孔一些比特比如删除所有c2和c5那么发送的序列就变成了c1, c3, c4, c6, ...。在接收端我们知道这些位置被删除了在解码时将这些位置的分支度量视为“无关”不参与距离计算。这样我们就用同一个1/2码的编码器和维特比解码器实现了2/3码率的通信。凿孔方案需要仔细设计以避免性能严重恶化。4.3 自由距离 (df)这是一个衡量卷积码自身纠错能力的理论指标。自由距离定义为任意两条不同的编码路径对应不同的信息序列其输出码字之间的最小汉明距离。直观上它代表了码字之间最小的“差异度”。df 越大意味着两条路径越不容易被混淆抗干扰能力越强。对于1/2码率的卷积码一个经典的 K7生成多项式为(171, 133)八进制的码其自由距离 df10这意味着在理论上它可以纠正连续floor((df-1)/2) 4个比特的错误在某些条件下。自由距离是评价一个卷积码“好坏”的核心参数之一好的生成多项式就是为了最大化自由距离。参数选择的权衡表参数提高该参数的影响带来的代价约束长度 K潜在纠错能力增强自由距离可能增大。解码复杂度指数增长状态数2^(K-1)时延增加。码率 R带宽效率提高在相同带宽下可传输更多有效信息。纠错能力下降冗余比特减少抗噪声能力减弱。自由距离 df直接提升纠错性能是编码设计的优化目标。通常通过优化生成多项式获得本身不直接增加复杂度但好的多项式往往对应稍复杂的连接。在实际系统设计中我们需要在可靠性纠错能力、频谱效率码率、实现复杂度K值和解码时延之间进行折衷。例如对于深空通信可靠性压倒一切会采用低码率如1/6、大约束长度K7,9的卷积码并结合后续的级联码。对于消费级Wi-Fi则在保证一定可靠性的前提下优先考虑高吞吐量和低成本会采用码率可变的、结合了凿孔技术的卷积码。5. 从理论到实战卷积码在真实系统中的应用与演进理解了基本原理和参数我们来看看卷积码是如何在真实的通信系统中发挥作用以及它后来如何演进。5.1 经典应用场景2G/3G 蜂窝移动通信GSM2G系统的语音和信道编码核心就是卷积码K5。CDMA20003G也大量使用卷积码进行信道编码。在这些系统中卷积码为语音通话的清晰度和控制信令的可靠性立下了汗马功劳。卫星通信与深空探测这是卷积码的“高光”领域。噪声极大、信噪比极低的信道环境正是卷积码维特比软判决解码大显身手的地方。旅行者号探测器向地球传回数据就使用了卷积码。Wi-Fi (802.11a/g/n)在802.11a/g/n时代物理层协议除了最高速率采用LDPC码外其他速率均采用卷积码K7码率可选1/2, 2/3, 3/4。当你用旧款路由器上网时数据包正是在卷积码的保护下穿越充满多径干扰和邻频干扰的空中链路。数字电视广播 (DVB-T, ATSC)地面数字电视信号容易受到建筑物反射、多普勒效应等影响卷积码作为内码与RS码等外码级联构成了强大的纠错体系保证了在移动中或信号边缘区域仍能稳定收看。5.2 级联码强强联合单独使用卷积码时如果遇到较长的突发错误性能会下降。因此实践中常采用级联码。最常见的是RS码 卷积码。外码RS码。一种强大的非二进制分组码特别擅长纠正突发错误和删除。它先将数据打包成块并进行编码。内码卷积码。对RS编码后的整个数据流再进行卷积编码。解码过程接收端先对卷积码进行维特比解码纠正随机错误然后将结果送入RS解码器纠正残留的突发错误。这种“卷积码在前RS码在后”的串联结构发挥了各自优势实现了“112”的效果在卫星、光盘存储等领域成为经典配置。5.3 Turbo码卷积码思想的登峰造极1993年发明的Turbo码可以看作是卷积码思想的革命性延伸它首次在香农极限附近实现了接近理论极限的性能。Turbo码的核心是两个或多个并联或串联的卷积编码器中间加一个交织器。解码时采用迭代解码的方式两个解码器互相交换“软信息”对每个比特是0或1的置信度经过多次迭代置信度越来越准最终性能远超单一的卷积码。3G和4G移动通信标准都将Turbo码作为主要的数据信道编码方案。5.4 被取代与新生LDPC码的崛起尽管卷积码和Turbo码非常成功但在追求更高吞吐量如5G eMBB场景和更低解码复杂度的驱动下LDPC码逐渐成为主流。5G的数据信道就采用了LDPC码。与需要序列解码的卷积码不同LDPC是一种分组码具有并行解码的特性更适合硬件实现在高吞吐量下功耗和时延更有优势。那么卷积码过时了吗绝非如此。控制信道在5G和Wi-Fi 6/7中对时延和可靠性要求极高的控制信道依然广泛使用咬尾卷积码。这是一种特殊的卷积码编码起始状态与结束状态相同无需添加尾比特归零提高了效率特别适合短包传输。轻量级应用在许多物联网设备、传感器网络、低功耗蓝牙等对成本和功耗极其敏感的场合结构简单、实现成熟的轻量级卷积码K3,4因其解码复杂度相对较低仍然是可靠的选择。作为组件卷积码编码器的结构移位寄存器线性反馈是许多现代编码技术的基础组件例如在一些神经网络译码器中卷积码的结构被抽象为可训练的层。踩坑实录尾比特与零状态冲刷在实际实现编码器时一个容易忽略的细节是终止。为了让解码器能从明确的已知状态通常是全零状态开始回溯我们需要在信息比特发送完毕后额外输入若干个K-1个“尾比特”将编码器的状态驱赶回全零状态。这个过程叫“零状态冲刷”。这些尾比特不携带信息是纯粹的开销。对于短数据包尾比特的开销比例可能很高会影响有效吞吐量。这就是为什么“咬尾卷积码”在短包场景下更受青睐——它通过将编码器的初始状态设置为信息序列末尾的K-1个比特使得编码器自然地在编码结束时回到初始状态省去了尾比特。在协议对接时一定要弄清楚对方使用的是传统卷积码带尾比特还是咬尾卷积码否则解码肯定会失败。卷积码的故事是一个从直观的“记忆”思想出发通过巧妙的网格图建模和维特比动态规划算法最终在无数通信设备中默默守护数据安全的经典工程案例。理解它不仅是理解一段通信历史更是掌握了一种在噪声中寻找秩序、在不确定性中做出最优推断的思维方法。下次当你的视频流畅播放时或许可以会心一笑知道其中有一段比特的旅程正被这个拥有“记忆”的编码算法精心呵护着。