4. 基带信号处理建模:信源编码与译码、信道编码(卷积码、Turbo码)、交织与解交织

各位同学,咱们今天聊聊基带信号处理里最核心的几个模块。说实话,这部分内容在仿真里特别容易「翻车」。我做了这么多年芯片,见过太多仿真跑得飞起、流片回来一塌糊涂的案例,问题往往就出在这些看似基础的编码和交织环节上。

4.1 信源编码与译码:压缩的艺术

信源编码,说白了就是把原始数据「挤一挤」。你想想看,一张高清图片、一段语音,如果不做压缩,那传输效率低得吓人。我个人习惯把信源编码分成两类:无损压缩有损压缩

  • 无损压缩:比如哈夫曼编码、算术编码。数据压缩后还能完美还原。我在做卫星通信芯片时,遥测数据就用的哈夫曼编码——丢一个比特都不行。
  • 有损压缩:比如语音里的ADPCM、图像里的JPEG。牺牲一点质量,换来巨大的压缩比。嗯,这里要注意:有损压缩的建模一定要考虑量化误差,否则你的系统级仿真会过于乐观。

避坑指南:我曾经在仿真里直接用浮点数做信源编码,结果硬件实现时发现定点化后的压缩率完全对不上。后来我学乖了——仿真一开始就用定点模型,哪怕精度低一点,至少不会出现「仿真通过、硬件翻车」的尴尬。

译码就是编码的逆过程。但要注意,译码器往往需要处理「边界情况」——比如码流长度不是整数、或者出现了非法码字。这些在仿真里很容易被忽略,但芯片一旦遇到就会死机。

4.2 信道编码:卷积码

信道编码是给数据穿上「防弹衣」。卷积码是其中最经典的一种。它的核心思想是:当前输出不仅取决于当前输入,还取决于之前几个时刻的输入。这就是所谓的「记忆性」。

我刚开始做卷积码时,总觉得维特比译码太复杂。后来发现,其实只要理解了网格图,一切都顺了。咱们看个简单的例子:

// 约束长度K=3,码率1/2的卷积码编码器
// 生成多项式:g0 = 111 (7), g1 = 101 (5)
void conv_encoder(int input_bit, int *state, int *out0, int *out1) {
    int shift_reg = (*state & 0x3);  // 取低2位
    *out0 = (input_bit ^ (shift_reg >> 1) ^ (shift_reg & 0x1)) & 0x1;
    *out1 = (input_bit ^ (shift_reg >> 1)) & 0x1;
    *state = ((*state << 1) | input_bit) & 0x3;
}

这段代码看着简单,但我在项目中遇到过一个问题:状态初始化。很多仿真里默认状态为0,但实际系统中,编码器在帧头需要做「归零处理」。如果你忘了这个细节,译码器在帧边界处会出错。

我的经验:仿真卷积码时,一定要把「尾比特」加进去。通常加K-1个0比特,让编码器状态归零。这样译码器才能正确开始下一帧。

4.3 信道编码:Turbo码

Turbo码是3G/4G时代的明星。它的核心是并行级联卷积码加上迭代译码。说白了,就是用两个简单的编码器,通过交织器连接,再用两个译码器互相「打气」,逼近香农极限。

Turbo码的建模难点在于迭代译码。我建议你记住这个关键点:

  • 分量译码器:通常用MAP算法或Log-MAP算法。MAP算法性能好但计算量大,Log-MAP在硬件里更实用。
  • 迭代次数:一般4-8次就够了。再多收益不大,反而增加延迟。我在做4G基带芯片时,迭代6次是性能和功耗的甜点。
  • 交织器:Turbo码的命门。交织器设计不好,编码增益会大打折扣。

警告:Turbo码的仿真收敛性是个大坑。我曾经遇到一个案例:仿真时迭代8次性能很好,但硬件实现时因为定点化精度不够,迭代到第5次就开始发散。所以,一定要在仿真里加入定点化模型,并且测试不同迭代次数下的收敛曲线。

Turbo码的译码流程大致如下:

  1. 接收软信息,初始化先验信息为0。
  2. 第一个分量译码器根据先验信息和系统位、校验位1,输出外信息。
  3. 外信息经过交织,作为第二个分量译码器的先验信息。
  4. 第二个分量译码器输出新的外信息,再解交织回去。
  5. 重复步骤2-4,直到达到迭代次数。
  6. 最后对软信息做硬判决,得到译码结果。

你想想看,这个过程是不是很像两个专家在互相讨论?一个说「我觉得是0」,另一个说「我觉得是1」,最后达成一致。这就是Turbo码名字的由来——像涡轮增压一样,越转越强。

4.4 交织与解交织:打散突发错误

交织的作用很简单:把连续的错误打散成随机错误。因为信道编码(比如卷积码)擅长纠正随机错误,但遇到突发错误就抓瞎了。交织就是让突发错误「均匀分布」到多个码字里。

常见的交织方式有:

交织类型 原理 适用场景
块交织 按行写入,按列读出 简单,延迟固定
卷积交织 用不同延迟的移位寄存器 连续数据流,延迟小
随机交织 用伪随机序列打乱顺序 Turbo码、LDPC码

我个人最喜欢块交织,因为它实现简单、延迟可控。但要注意:交织深度的选择很关键。深度太小,打散效果不好;深度太大,延迟受不了。我在做DVB-T2芯片时,交织深度选的是6144个符号——这是性能和延迟的折中。

避坑指南:我曾经在仿真里用随机交织,但忘了把交织表存下来。结果译码时解交织表对不上,整个系统崩溃。后来我养成了一个习惯:仿真代码里,交织表和解交织表一定要成对生成,并且用同一个种子

解交织就是交织的逆过程。没什么技术难度,但要注意边界处理。比如块交织的最后一行可能不满,需要填充虚拟比特。这些虚拟比特在解交织后要丢弃,否则会影响译码性能。

4.5 小结

好了,咱们把基带信号处理的几个关键模块过了一遍。信源编码负责压缩,信道编码负责纠错,交织负责打散错误。这三者配合好了,你的通信系统才能在恶劣信道下稳定工作。

最后说一句:仿真不是终点,硬件实现才是。我见过太多仿真完美、硬件翻车的案例。所以,从第一天开始,就要用「硬件思维」去做仿真——考虑定点化、考虑延迟、考虑资源消耗。这样你的仿真才有真正的工程价值。