
简介面向数字通信与FPGA开发者的VHDL加扰与解扰工程包完整演示了从算法建模到硬件验证的流程。加扰用于将连续1/0序列随机化降低信道中的自相关干扰解扰则在接收端恢复原始数据是数字电视、LTE/5G及卫星通信的常见基础模块。压缩包共132个文件、约1.37MB包含VHDL工程源码vhd、Xilinx工程配置xise、综合及布线结果ngc/ncd、比特流文件bit、引脚约束ucf及大量仿真与报告文件可导入Modelsim或Vivado/ISE直接复现与调试。已有2488人学习适合通信工程、电子信息类学生及FPGA入门开发者。资源内提供test_scramb相关测试用例与完整工程记录可对照理解加扰解扰的原理、VHDL代码风格以及Modelsim仿真到板卡下载的完整操作路径是一份难得的实战参考资料。 如果你在通信、广电或者芯片行业待过一定绕不开加扰与解扰这两个词。它们经常手拉手出现在链路框图和芯片手册里发送端一个加扰器接收端一个解扰器。问题是很多人会下意识把它们和加密/解密混在一起其实这是完全不同的两条思路。我最早被这个概念搞晕是在调一条卫星接收链路的时候。文档里白纸黑字写着MPEG-TS码流需经过加扰以完成能量扩散我盯着这句话想了半天加扰不是用来防止别人看内容的吗怎么又变成能量扩散了直到后来我把加扰器、解扰器从理论到板子都碰了一遍才搞明白这事的来龙去脉。这篇文章我想把这套东西掰开揉碎讲清楚尤其是那些标准文档里不太会写的工程坑。简单说加扰就是用一个确定性的伪随机序列去搅动原始数据流让它在物理传输时可以更稳定解扰则是接收端用同样的规则把数据还原。它既是通信物理层的基石也是数字电视内容保护的一环。不管你是做FPGA开发、协议分析还是调试高频串行链路都值得把这块知识补扎实。1. 从连续长0说起加扰到底解决什么问题1.1 没有加扰时物理链路会发生什么先放下那些高大上的公式我们从最底层的物理限制谈起。假设发送端要把一段数据用高速串行方式传过去接收端不是拿示波器直接读0或1而是需要一个时钟恢复电路CDR从信号的边沿中挖出采样时钟。如果数据流里出现几十上百个连续的0电平就一直趴在低电平上没有任何跳变沿CDR的锁相环会失去参考等边沿终于到来时采样相位已经不知道漂到哪里去了误码就来了。数据传输速率越高这个问题越严重因为单位时间内的漂移量是按比例增大的。这个坑不是我编的标准制定人员早就被坑过无数次所以几乎所有高速串行标准都会强制要求对原始数据先做处理处理方式之一就是加扰。加扰器把原始比特和伪随机序列做异或让输出数据中几乎不可能出现超长连0或连1从而保证CDR始终能看见边沿。你可以这么理解加扰相当于往一串单调的文本里故意插入一些标点符号让阅读的人始终有节奏感不至于盯着一个空白页发呆。1.2 能量扩散与频谱整形加扰的另一重价值把数据从时域拿到频域看又是另一番情景。如果码流里有周期性重复的字段比如帧头、填充、同步字它的能量会集中到几个离散频率上在频谱上形成尖峰。在卫星通信里这尖峰可能超过邻道干扰模板在电缆传输中它也会抬高本底干扰。加扰后数据变成类似白噪声的伪随机序列频谱被摊平峰值功率大幅降低。这个动作标准里常叫能量扩散Energy Dispersal。比如DVB-S系统TS流在进入卷积编码之前必须经过一个由标准定义的能量扩散加扰器目的就是避免调制信号在某些业务模式下出现不达标的频谱尖峰。如果你误以为这是为了加密就会完全理解错它的行为特征它不依赖任何密钥只要多项式对、相位对任何人都能解出来。它更像给数据洗牌而不是上锁。有时候我在想为什么加扰一个看起来是安全领域的词会出现在物理层的规范里因为加扰本来就有两层意义物理层加扰是为了信号完整性和频谱规范性内容层加扰才是为了访问控制。它们共用了移位寄存器、伪随机序列这些工具但目标完全不同。把这层逻辑先理清楚后面看各种标准就不会晕。2. 加扰器的核心伪随机序列与线性反馈移位寄存器2.1 一个m序列是怎么生成的加扰器做的事情归纳起来就两件事本地产生一个伪随机序列把数据和它异或。难点在伪随机序列这五个字上——为什么要伪因为真正的随机序列接收端根本没法复现必须由一个确定性的、对外人来说看起来随机的序列来参加运算接收端只要拿到同样的种子和规则就能生成一模一样的序列。最常见的生成电路就是LFSR线性反馈移位寄存器。以最简单的4级LFSR为例移位寄存器有4个状态位每来一个时钟根据抽头位的异或反馈更新最高位其余位依次右移。输出那一位通常是最低位就是当前时刻的PN码比特。当多项式是本原多项式时4级寄存器会产生周期为2^4-115的序列如果选得不对周期就短得多甚至可能陷入短循环。下面是一段非常简化的Python示意帮你理解加扰器的数据流def lfsr(seed, taps, n): reg seed 0b1111 seq [] for _ in range(n): seq.append(reg 1) fb 0 for t in taps: fb ^ (reg (t - 1)) 1 reg ((reg 1) | (fb 3)) 0b1111 return seq # 假设多项式为 x^4 x^1 1对应抽头位置 4 和 1 pn lfsr(0b1111, (4, 1), 20) print(pn)实际工程中这个LFSR会被做成硬件模块每一个时钟周期输出1 bit伪随机序列将输入数据比特与这个序列异或得到加扰后的数据。解扰端再做一次同样的异或就能还原数据。整个过程在硬件里也就是几十个逻辑门但它的价值是让整条链路都稳定下来。2.2 多项式选择为什么是x^16x^5x^3x^21这种形式你翻标准时会看到一堆诡异的多项式比如PCIe 3.0的加扰多项式是x^23 x^21 x^16 x^8 x^5 x^2 1DVB能量扩散加扰多项式是x^15 x^14 1。这些多项式不是拍脑袋定的它们必须是本原多项式primitive polynomial也就是能让LFSR遍历除全0外的所有状态、产生最大长度序列的多项式。只有这样输出序列才足够接近白噪声自相关特性好不会出现短周期重复。如果多项式选成非本原的后果很隐蔽输出序列的周期短了频谱上会重新出现离散尖峰同时某些数据模式下可能产生较长的连0或连1刚好抵消掉加扰的意义。工程上如果要做私有加扰器我的建议是直接查表用已知的本原多项式不要自己推导。网上有现成的本原多项式表按需要的移位寄存器级数挑一个即可。标准里已经给出多项式的场景就老老实实按标准实现这往往能少踩很多坑。这里需要提醒一句LFSR不是唯一产生伪随机序列的方式比如CDMA系统里常用Gold序列也是基于m序列组合出来的。但无论哪种序列核心思想都一样确定性的生成规则 足够的随机外观。3. 解扰端不是简单反过来两种解扰同步架构3.1 自同步加扰从接收序列中自己找出路很多人以为解扰器就是把加扰器倒过来搭这话对了一半。加扰器确实有一个逆结构但这个逆结构分两种实现路径其中一种叫自同步加扰。自同步加扰的典型结构是发送端的当前输出 当前输入 ⊕ 若干延迟位的输入接收端的当前输出 当前输入 ⊕ 对应延迟位的接收数据。因为接收端使用的反馈信号不是本地生成的而是直接从接收序列中延迟取出的所以不需要知道发送端的初始状态。它会在收到数据后的若干比特内自动进入状态后续输出就是正确的解扰数据。优点是无需额外的同步握手适合连续比特流的链路比如SDH、背板串行传输。代价也很明显误码扩散。假设延迟级数是M那么接收数据里的一个比特错误会进入延迟寄存器之后M个时钟周期内解扰输出都会受到影响。换句话说一次传输错误会被放大成M1次输出错误。我在做误码测试时就碰到过这个问题信道误码率明明只有1e-7解扰后的误码率却显示1e-5一开始还以为设备坏了后来才想起自同步加扰的误码扩散效应。3.2 同步加扰先锁定相位再解扰同步加扰是另一种更常见的架构在数字电视和分组化业务里非常普遍。它的思路是发送端和接收端各有一个完全相同的LFSR初始种子也相同加扰时逐比特异或PN序列接收端必须先通过某些方式知道当前数据帧中哪个位置是加扰的起点也就是锁定PN序列的相位然后从该起点开始生成本地PN序列进行解扰。这个锁定相位的过程通常靠帧头的固定同步字完成。接收端搜索到同步字后将本地LFSR重置到约定状态然后开始解扰。同步字的自相关性必须足够好否则加扰后的码流里可能出现伪同步字导致误同步。工程上通常还要加一个滞回机制连续三次找不到同步字才判定失步连续三次找到同步字才进入同步状态这样能避免偶发误码造成同步状态来回抖动。同步加扰的优点是一个比特错误不会向后扩散因为解扰用的是本地生成的PN序列而不是接收数据的延迟反馈。缺点是一旦发生位滑bit slip或帧错位同步会瞬间丢失需要重新搜索同步字。所以在有明确帧结构的系统里同步加扰是更稳妥的选择。下面用一个表格把两种架构的差异总结一下维度自同步加扰同步加扰初始同步自动收敛无需额外握手必须通过同步字或定时信息获取相位误码扩散单比特错误扩散为多个错误无扩散单比特错误只影响一位实现复杂度简单反馈取自接收序列中等需要本地LFSR和同步状态机典型场景连续位流、SDH、部分背板串行分组化业务、TS流、协议帧4. 现实中那些被称为加扰的场景其实各有各的侧重4.1 数字电视条件接收加扰之后的业务密钥交换提到加扰很多人第一反应就是数字电视CA系统。这里的加扰和前面讲的物理层加扰虽然名字一样但完全是两码事。DVB条件接收系统里TS码流用控制字Control Word简称CW对净荷进行加扰CW本身再用RSA或AES等算法加密后放进ECM授权控制信息和EMM授权管理信息里传输。机顶盒用智能卡中的密钥解开ECM才能拿到CW再对TS流解扰。注意这里的加扰算法是标准定义的CSACommon Scrambling Algorithm它是一个面向MPEG-TS的对称分组/流混合算法绝不是简单的LFSR异或。CW也绝不是LFSR种子那么简单——CW是加密密钥安全性完全依赖它的更新频率和保密性。我见过有同学把这两层混在一起以为只要把TS流做一次m序列异或就完成了加扰这在CA系统里是行不通的因为m序列是线性可预测的攻击者只要拿到一段明文和密文对就能逆出整个序列。如果你只是做前端复用器和加扰器的联调一定要区分CAS加扰和物理层加扰两个模块在链路中的位置物理层加扰通常在最外层的线路接口CAS加扰则在TS流复用之后、调制之前。两者功能不能互相替代。4.2 高速串行总线PCIe/USB里的加扰与时钟恢复PCIe 3.0和USB 3.0这类高速串行总线是物理层加扰的另一个典型战场。PCIe 3.0取消了8b/10b编码改用128b/130b编码然后在物理层对数据进行加扰用的就是前面提到的23级LFSR多项式。加扰后数据流中连续相同比特的最大长度被严格限制这样接收端的CDR电路可以稳定工作同时直流平衡特性也更好。在这个场景下加扰的目的和内容安全一点关系都没有。它纯粹是为了提升链路的信号完整性。所以当你用协议分析仪抓PCIe流量时看到的链路数据其实是加扰后的而分析仪会自动完成解扰把呈现给使用者的数据还原成原始逻辑数据。如果这一层解扰出错你看到的协议层数据就会充满CRC错误和重传可这个现象背后的根因可能是物理层位滑而不是协议层本身的毛病。很多工程师排查PCIe链路复位、链路训练失败问题时容易在协议层转圈其实先看一下物理层加扰解扰有没有失锁往往更快。4.3 CDMA/扩频通信PN码加扰如何区分用户CDMA系统里的加扰又换了一副面孔每个用户的数据先用正交沃尔什码扩频再用一个长PN码进行加扰这个PN码常被称为扰码。接收端只有同时知道用户的正交码和扰码相位才能在射频信号中把该用户的数据正确解扩和解扰。这里的加扰不是解决时钟恢复问题而是实现小区识别、用户区分和信号随机化。从公司做LTE或5G物理层算法的朋友那里你应该也听过小区加扰这个词它用的就是Gold序列。这里的Gold序列同样属于伪随机序列但它的生成方式是基于两个m序列的模二和目的是获得更好的互相关特性让不同小区、不同用户之间的干扰更像噪声。你会发现无论场景怎么变加扰的统一逻辑始终是发送端生成本地伪随机序列对数据进行扰乱接收端同步到同一序列再把数据恢复出来。把握住这个框架再去看不同协议的具体定义就不会迷路。5. 调试加扰解扰链路时最容易栽的五个跟头5.1 同步丢失解扰器吐出一堆乱码的根本原因同步丢失是我在调试中遇到最多的故障现象。逻辑分析仪上解扰输出每隔一段时间就出现一小段乱码看起来毫无规律。遇到这种情况先别急着怀疑加扰算法第一步检查加扰器和解扰器的复位时序是否对齐。尤其在FPGA里如果加扰器复位后等了多少个时钟才启动解扰器也必须在同样的延迟后启动否则整条流相位对不上输出的前几百比特全是错的。我遇到过一起很隐蔽的问题加扰器和解扰器虽然都用同一个复位信号但解扰器那边的复位树多打了两拍导致解扰器启动晚于加扰器约两个时钟。结果是每帧数据的前两个字节解错后面所有数据正确CRC却每帧都报错。当时花了大半天才在时序报告里发现复位信号到达时间差加上一个全局同步复位才解决。所以调试这类问题优先检查同步使能时序不要一上来就翻多项式。5.2 初始化种子和多项式不匹配种子不匹配也是个经典问题尤其在标准文档实现时。不同标准对LFSR初始值的定义不一样有的要求全1有的要求全0还有的要求特定常数。如果发送端初始化为0xFFFF接收端却初始化为0x0000解扰出来的前N个比特必然全部错误之后也可能因为序列相位偏移而持续错误。更隐蔽的是位序问题。同一个多项式有的文档定义最高位先出有的定义最低位先出没有对齐时两边LFSR的抽头看起来完全不同。我的建议是实现时把多项式、初始种子、输出位序全部做成参数并且在testbench里做一个加扰-环回-解扰的自检比对输入输出完全一致后才能上板。这个自检只要一秒钟能帮你省下无数排查时间。5.3 误码扩散自同步解扰的一个隐形成本前面已经提到自同步解扰器会把单比特错误放大成多个错误这是它的数学结构决定的。在工程测量中这个效应会让误码指标变得十分难看。假如链路原始误码率是1e-7经过自同步解扰器后输出误码率可能达到1e-5甚至更高具体放大倍数取决于反馈抽头的延迟级数。如果你在做系统预算必须把这个放大效应算进去。否则你会误判链路性能以为信道质量不达标其实只是选错了加扰结构。如果业务对误码扩散敏感尽量选择同步加扰架构如果硬件资源受限只能使用自同步结构那就要在解扰后做好纠错或重传机制。5.4 加扰后还是出现长连0多半是多项式选错了有些设计者以为加了加扰就不会再有长连0可实测数据里还是会出现超出规则的游程。排除LFSR实现错误后通常有两个原因第一多项式不是本原多项式生成的序列周期太短或者输出序列的游程分布不佳第二你用的数据模式比较极端恰好让加扰后的输出残留了极少数长游程虽然概率低但长期跑业务时总会碰到。遇到这种问题最直接的手段是用PRBS7、PRBS15、PRBS23等标准测试码型去遍历在接收端统计连续相同比特的最大长度。如果加扰后最大游程仍然超过链路规定的上限就要调整LFSR的相位偏移或者配合DC均衡编码来兜底。注意如果加扰多项式是标准强制规定的你不能随便改常数只能通过数据预处理或后续编码让情况变好。5.5 从示波器上误判加扰不等于随机化最后说一个偏测试习惯的问题。示波器上看加扰后的信号眼图往往显得比较杂乱尤其是多电平串行信号但你千万不要因此认为链路故障。加扰后的数据虽然是伪随机但它仍然有确定性的电平和时序关系正常眼图应该是有清晰的眼模板的只是信号跳变密度比学习序列高很多看起来更毛糙。真正需要关注的是眼图是否闭合、是否有明显的过冲或欠冲而不是它看起来像不像随机噪声。我见过有同事把正常加扰后的眼图当成串扰问题拉着硬件团队排查了两天最后把加扰模式关掉才发现不关事只是自己看习惯了未加扰的规律波形。做这类测试建议配合误码仪或协议分析仪一起判断凭肉眼判趋势可以判故障还是要用指标说话。6. 最后再分享两个工程技巧6.1 先做自检再做联调调试解扰器的时候我习惯先在输入端接一根固定的PRBS测试序列不加真实业务。具体做法是发送端用LFSR生成一段PRBS经过加扰器后直接灌给解扰器再把解扰器输出和原始PRBS逐比特比对。如果比对通过说明加扰器、解扰器单个模块都没问题只有这步通过了才连上真实业务码流。这一步可以快速把问题定位在物理链路还是模块自身省掉大量无意义的联调时间。6.2 同步字要防伪进入同步要滞回设计同步加扰系统时同步字的选择非常关键。同步字本身有良好的自相关特性还不够还要考虑加扰后码流中可能出现与该同步字完全相同的位组合。如果接收端见到一次就进入同步大概率会被伪同步骗到。稳妥的做法是要求连续两到三次搜到同步字才进入同步状态同样连续多次找不到同步字才宣告失步。这个滞回机制虽然会让同步建立时间多一点但换来的抗扰性是完全值得的。我实际做过的系统里同步字选择0x47这种TV标准里的同步字节并且做连续3次确认运行一年下来失步次数屈指可数。加扰与解扰是一对镜像但镜像的复杂度往往在同步上。真正做过一次就明白解扰最大的难点不是异或逻辑而是让两边确认彼此在同一个位置上开始。理解这一点比记住一百个多项式都管用。本文还有配套的精品资源点击获取