FPGA平台下Gardner环多径信道定时同步测试与抗多径优化
发布时间:2026/10/24 0:30:00 锦皓数字建站

连续做Gardner环性能测试第二轮我直接把信号扔进带多径的信道里。上篇内容是不同信噪比下定时收敛的表现测完之后有两个疑问没有解决高斯噪声是随机干扰Gardner环可以通过环路滤波平均掉一部分但多径是确定性干扰它把符号波形直接“扯歪”了定时误差检测器看到的过零点不再干净。我在FPGA平台上跑完这轮测试后最大的感想是——多径对Gardner环的影响和噪声完全不同它动的不是误差方差而是误差检测的“基准”。这篇文章把多径拆成两个维度一个是多径时延以符号周期T的倍数衡量另一个是多径幅度相对主信号的衰减分贝数逐组合测了一遍并且把结果量化下来。我采用的平台和上篇保持同一条流水线Vivado里搭System Generator做信道激励和采集核心Gardner环用可综合RTL重写最后用ModelSim和Vivado Simulator交替做回归仿真。信号制式是QPSK符号速率定在1 Msps过采样率4倍符号定时的捕获由环内的NCO和Farrow插值器完成。写完这个平台之后我对着手里的旧代码发现一个问题多数FPGA工程示例里把Gardner环放在理想信道下验证一旦引入多径环路参数是否还合适、插值器的精度是否够根本没人给现成答案。所以这篇更准确地说不是“又做了个波形仿真”而是把工程里最容易忽略的信道敏感性拿到台面上量化。无论你是刚开始搭定时同步链路还是已经在FPGA项目里跑过Gardner环下面的实现细节和故障排查都值得对照一遍。1. 为什么第二轮测试要拿多径开刀1.1 多径的延迟和幅度如何扭曲Gardner环的S曲线Gardner定时误差检测器的本质是利用相邻符号的中间点与两端符号值之间的相关关系估计定时偏移。无多径时匹配滤波后的眼图过零点对称误差检测输出和定时偏差之间呈一条平滑的S形曲线环路沿着S曲线把采样点拉回眼图中心。多径信道不一样它相当于在原信号上叠加一个经过衰减和延迟的副本。副本与主路径叠加后符号脉冲的上升沿和下降沿不再对称眼图的过零点位置发生平移。我在测试里用两径模型控制时延τ和幅度α时延从0.1T逐步加到0.8T幅度从-20dB加到-3dB。当τ等于0.5T附近时过零点平移最明显定时误差检测器的S曲线零点整体偏移了接近0.13个符号周期。这个偏移不是噪声抖动它是固定偏置环路滤波器压不掉看起来像是把采样点锁在一个偏移的位置上实际就是在多径环境下“锁错了地方”。这里还得强调一个机理Gardner环本身不感知绝对时钟相位它只能跟随S曲线的零点。多径引入零点偏移后环路认为的“正确采样点”已经偏离真实最佳均衡点最终剩余误差不再是零而是这个偏置。工程上最容易踩的坑是把这种固定偏置误判成环路没收敛去调大环路带宽实际上增大带宽只会增加稳态抖动并不会把偏置消掉。这个机理理解透后面看测试数据就顺了。1.2 测试想回答的三个问题和信号参数快照这次测试我给自己的目标非常具体不指望把所有多径场景全测全。第一个问题是多径时延大小会如何影响收敛速度——Gardner环从上电到锁定需要多少个符号周期第二个问题是多径幅度如何影响稳态定时抖动以及最终误码率第三个问题是多径强到什么程度会直接导致环失锁。围绕这三个问题我固定了一组基线参数QPSK、符号速率1 Msps、4倍过采样、成形滤波采用滚降系数0.25的根升余弦滤波器定时环的归一化环路带宽BL·T设为0.02。所有测试都在相同信噪比20dB下进行隔离其他因素单独观察多径维度。这么做的好处是结果之间可以直接横向对比上一轮测不同SNR的数据也还能复用。参数上还有一个细节需要交代多径时延的分档。我选了0.1T、0.25T、0.5T、0.8T四档0.5T是最恶劣的挡位因为正交信号在符号中点的相干叠加最容易造成符号间干扰。幅度分档是-20dB、-10dB、-6dB、-3dB-3dB基本对应接收端副径与主径幅度相当的极限场景。在这个参数快照下每一组都跑满2^16个符号重复30次统计锁定时间和失锁比例。整轮测试大约四十多组仿真跑起来并不慢但能把问题的边界画清楚。2. 先把手头的Gardner环拆开看为了让多径测试结论可靠我不可能拿黑盒去做分析必须把FPGA里跑的定时环每一个模块都过一遍。Gardner环在FPGA中可以拆成四个部分定时误差检测器TED、环路滤波器、NCO、插值器。很多工程问题不是算法不对而是定点实现和模块间的延迟把环路带宽或误差增益悄悄改变了。尤其是在多径存在的场景TED输出幅度随信道变化很大如果不做归一化环路实际带宽会随信道状态漂移后面看数据就会“找不到原因”。2.1 TED、Farrow插值器与定点的三层坑TED实现上需要当前符号采样值y(k)、前一符号采样值y(k-1)以及两者中间的半符号采样值y(k-1/2)。QPSK的I/Q两路都要参与实际误差值取复平面组合要按接收机结构决定。我这边采用复数形式e(k) Re{y(k-1/2)·(y*(k) - y*(k-1))}。中间点采样并不是ADC直接给出的是靠插值器在过采样序列里计算出来的小数延迟点。FPGA里我用了四阶Farrow结构用当前点前后四个采样值做三次多项式插值。定点位宽上输入样值用了16bitFarrow系数用16bit有符号数插值结果保留到20bit。这个结构在无多径场景表现很好误差精度能到0.001符号周期以内但在多径测试中我发现如果插值器系数位宽不足多径造成的高频分量会直接变成插值噪声结果比信道本身的损伤还明显。这个教训后面专门说。误差算法本身不复杂我贴一段Verilog摘要展示实现思路// Gardner TED核心QPSK I/Q两路 wire signed [19:0] mI interp_I; // 半符号点I wire signed [19:0] s0I cur_I; // 当前符号I wire signed [19:0] s1I prev_I; // 前一个符号I wire signed [19:0] errI mI * (s0I - s1I); // I路误差 wire signed [19:0] mQ interp_Q; wire signed [19:0] s0Q cur_Q; wire signed [19:0] s1Q prev_Q; wire signed [19:0] errQ mQ * (s0Q - s1Q); // Q路误差 reg signed [19:0] e_ted; always (posedge clk) begin e_ted (errI errQ) TED_SHIFT; // 归一化右移 end真正定点实现时乘法器要配DSP48并且根据仿真结果确定TED_SHIFT的值。我在无多径信道下先做一遍浮点模型与定点模型的对比把量化误差控制在2%以内才放心进入多径测试。2.2 环路滤波器、NCO与带宽选择的折中环路滤波器和NCO决定了环的动态特性。我用的是二阶环路比例支路Kp负责直接对当前误差做出响应积分支路Ki负责消除静态误差。由于Gardner环工作在符号率上NCO实际上是一个相位累加器每次迭代输出的小数相位控制Farrow插值器累加器位宽我用了24bit这决定了可调频率分辨率。归一化带宽BL·T是设计时输入量我给出常用对应关系BL·TKpKi特点0.010.0280.0004捕获慢抗噪声强适合高SNR但需稳定0.020.0560.0015折中本文测试默认0.050.1410.01捕获快稳态抖动大这张表是PI参数换算后的经验值实际还需要根据环路延迟微调。多径场景下我认为最关键的取舍在“带宽能不能跟着多径强度变”多径产生的定时自噪声主要落在低频区把BL·T收窄能压住自噪声但会使环对时变信道失去跟踪能力。没有自适应环路的前提下我把默认带宽定在0.02是在上一轮SNR测试基础上找的平衡点。后面跑多径用例时凡是抖动异常增大的用例我都额外补跑BL·T等于0.01和0.05的对照用来判断是信道损伤还是环路带宽不匹配。3. 多径注入与性能测试工程实现测试工程搭建时最重要的决定是“多径信道在哪里注入”。我之前见过有人直接用MATLAB把多径信号算好写成文件再在Testbench里读文件灌给RTL也有人用System Generator的FIR抽头模型在线生成。两种都可以但我为了保证后续板级验证能直接复用选择了在RTL侧用抽头延迟线加乘法器做成一个参数可配的信道模型。3.1 两径信道模型从解耦参数到FPGA建模两径模型就一句话输出 当前样值 副径系数 × 延迟后的样值。困难在延迟不一定是整数个采样点。比如符号周期T对应4个采样点时延0.25T对应的就是1个采样周期可以用寄存器链直接取而0.1T对应0.4个采样点寄存器链没法直接给分数延迟必须再做一次插值。我的做法是先用一个独立Farrow插值器把当前序列做分数延迟再把输出乘以幅度系数后叠加到主路径上。这里有个容易被忽略的问题多径叠加后信号总功率会上升如果不做归一化进入TED的信号幅度变化会被误读成定时误差变化。我按主径幅度1、副径幅度β归一化总能量代码里乘上一个固定因子1/sqrt(1β²)确保不同用例之间S曲线增益可比。信道模型参数表如下我用寄存器字控制用例组多径时延多径幅度系数β数字化16bitT10.1T-10dB0.316T20.25T-10dB0.316T30.5T-10dB0.316T40.8T-10dB0.316A10.25T-20dB0.100A20.25T-6dB0.501A30.25T-3dB0.708T1-T4观察时延维度的变化A1-A3观察幅度维度的变化中间用0.25T、-10dB这组交叉用例保证两组可以直接对比。这组参数听起来很直观但第一次跑的时候我踩了坑副径时延在Tx信号发生端和信道模型是两套时钟域如果省掉异步处理在仿真里会出现随机毛刺。后来统一把整个信道模型放在ADC采样时钟域激励从ROM里按同一时钟读问题才消失。3.2 Testbench与统计模块用寄存器输出性能指标性能测试不能靠眼睛盯着ModelSim波形数刻度那不叫测试。我往RTL里嵌了一个统计模块用AXI-Lite寄存器把实时指标读出来。每个符号周期统计模块做四件事记录TED输出的瞬时值、累计定时误差平方和、统计锁定标志的跳变次数、记录从启动到锁定的符号计数。为了把锁定定义具体化我在统计模块里设置“误差滑动平均值小于0.05符号周期并连续保持2^10个符号周期”作为锁定条件。同时为了测试公平每次仿真开始时NCO初始相位不是一个固定值而是用线性反馈移位寄存器产生随机符号内偏移避免初始相位恰好落在S曲线零点附近而“假锁定”。激励侧的安排也值得提一下QPSK基带信号用MATLAB生成经过根升余弦成形、量化成16bit样值后写到COE文件Testbench用$readmemh读入ROM。每个用例更换信道参数实际上只需要重新生成信道仿真文件或者通过寄存器实时配置抽头系数和延迟。跑完所有用例再用MATLAB脚本解析仿真导出的寄存器数据画收敛曲线和抖动分布。这套流程并不复杂但统计口径统一横向对比才有意义。3.3 数据采集与指标定义最终我采了六个指标平均收敛符号数、失锁概率、稳态定时抖动σ_e、眼图张开度、误码率、TED输出均值。其中σ_e的定义是锁定后定时误差序列的标准差单位是符号周期眼图张开度我用过零点附近采样点的同相幅度比值来近似反映可解码裕量。误码率在仿真里直接做符号级硬判每用例统计2^16符号。这里有一个细节单独仿真定时环时看不出误码需要把定时环输出的插值样值送到后续匹配滤波和判决器里才能反映出定时质量对链路最终性能的影响。我这轮把判决器一起跑通了因此后面的误码数据是端到端结果不是孤立的定时误差换算值。4. 不同多径大小下的实测结果数据就跑完了开始看结论。整体来说多径对Gardner环的影响是“温和时延先拖慢收敛幅度再决定抖动上限”。我先把两个维度的数据分开讲再合起来解释S曲线变化的机理。4.1 时延维度收敛速度先降、锁定点再偏移固定多径幅度-10dB、SNR 20dB改变时延收敛时间和锁定点偏移的数据统计如下多径时延平均收敛符号数锁定点偏移符号失锁概率无多径4520.0021%0.1T473-0.0081%0.25T7120.0522%0.5T13310.1178%0.8T18020.12425%可以看到0.1T时几乎没影响从0.25T开始收敛时间和锁定点偏移明显上升到0.5T时最典型的问题已经不只是慢而是锁定点被拉到约0.117个符号周期——这个偏移换算成采样相位就是约42度对QPSK解调器来说已经非常可观。0.8T那组失锁概率上升到25%说明环路在不同初始相位下经常找不到正确的S曲线零点偶尔会锁定到相邻的伪零点上去。还有一个细节值得注意0.5T和0.8T的锁定点偏移都在0.12符号附近与单符号信道记忆理论的预期基本一致过零点偏移在半个符号时延附近趋于饱和。时延变化改变的是符号间干扰的“作用位置”。小于0.1T的时延等效为信道群延迟Gardner环完全可以吸收掉看起来只是把采样点整体移动了一下当延迟接近并超过半个符号副径会直接落在相邻符号的判决点附近码间干扰的能量进入TED计算窗口S曲线的过零点不再单调锁相过程开始出现多个准平衡点。这就是为什么收敛符号数从400多跳到1800不是单纯变慢而是环路搜索机制在多准平衡点环境里总在反复试探。4.2 幅度维度抖动与误码呈非线性增长固定多径时延0.25T、SNR 20dB改变多径幅度结果如下多径幅度稳态σ_e符号眼图张开度误码率BER无多径0.01699%1e-5-20dB0.02295%1e-5-10dB0.03586%4e-4-6dB0.05873%6e-3-3dB0.12742%1.4e-2第一眼看σ_e从0.035跳到0.127增幅明显大于线性这说明多径造成的定时自噪声与副径幅度不是简单的比例关系。原因在于多径不仅增加了误差检测的自噪声还改变了误差检测增益副径幅度越大TED输出中的确定性偏置越强环路试图把偏置积分掉的同时又把大量ISI相关的波动放大成抖动。眼图张开度在-3dB时掉到42%这已经是基带解调基本不可用的水平。另一个值得一提的现象是多径幅度相同但时延不同时抖动差异非常大在-6dB、时延0.25T的条件下σ_e约0.058而同样的幅度在时延0.5T时σ_e会上升到接近0.09。所以多径的影响应该看“时延幅度”的组合单独给一个“有多少dB多径”并不能说明问题。误码与抖动的折算也值得深入看0.127个符号的定时抖动对QPSK在20dB信噪比下造成的误码率下降远超预期。因为定时偏移直接造成采样点偏离符号中心等价于降低了有效信噪比。估算下来-3dB多径带来的等效SNR损失大约在5到6dB。这个数字并不新奇但FPGA实测能稳定复现就有参考价值了。4.3 用S曲线解释为什么多径这么难缠为了把数据背后的东西讲清楚我把TED的输出在每个固定的定时偏移下扫一遍得到S曲线。无多径情况下S曲线是一条过零点附近基本线性的平滑曲线。加入0.5T时延、-10dB幅度后曲线形态发生两个变化过零点向右平移约0.12符号过零点附近的斜率从约0.5下降到约0.34。斜率下降意味着环路增益变小同样的误差电压对NCO的拉动力下降所以收敛变慢零点平移意味着即使在稳态误差均值也不为零固定偏置始终存在。这两个变化放在一起就解释了前面所有数据收敛慢是斜率下降的结果锁定点偏移是零点平移的结果失锁概率上升则是S曲线在远离零点区域出现非单调甚至局部极小值的直接后果。对FPGA开发人员来说S曲线不是算法课上的抽象概念它是可以用硬件扫描出来的关键曲线。我在工程里用寄存器把TED输出按偏移量分桶统计300毫秒左右就能把S曲线扫出来调试多径问题比看一堆抖动波形直观得多。如果你也在处理类似问题强烈建议在测试模块里加一个“S曲线扫描”模式短时间内能省下大量排查时间。5. 踩坑清单、抗多径思路与后续方向把最值钱的故障排除经验放在最后。多径测试不是灌一个信号看波形就行这轮跑下来我在工程细节上抓出几个典型问题都值得记录。5.1 踩过的三个坑分数延迟、归一化与带宽误判第一个坑就是多径分数延迟。最初图省事时延直接从采样点抽整数拍0.25T、0.5T能整数对应没关系但0.1T和0.8T两档就出问题了——用整数延迟替代分数延迟后0.1T的测试结果与理论完全不匹配S曲线零点偏移几乎为零但抖动异常增大。后来查清是整数延迟在相邻采样点之间“跳变”产生了额外的相位噪声。解决方法是把分数延迟统一用独立Farrow插值器生成确保任意时延都能连续变化。第二个坑是信道增益没有归一化。多径叠加让信号平均功率变大TED输出的幅度整体上抬统计模块算出来的“均值”不再能反映真实定时偏移。我在信道模型里加了固定能量归一化系数1/sqrt(1β²)把主径加副径的总功率归一化回单位功率所有用例的TED均值才具有可比性。第三个坑最隐蔽把环路带宽太宽导致的自噪声误判为多径失锁。刚开始用BL·T0.05跑-3dB用例看到σ_e冲到0.17以上差点结论写成“系统失锁”后来补跑BL·T0.01的对照σ_e立刻降到0.11发现10dB多径并没有让环完全失锁只是宽带宽放大了多径自噪声。这个错误在无多径测试中发现不了因为高斯噪声被环路滤掉后自噪声的贡献很小多径的时序相关噪声会让宽带宽付出明显代价。5.2 工程上实用的抗多径优化措施从这轮测试看多径环境下的Gardner环设计不能指望换算法一劳永逸但有几个工程手段能把环境影响压下来。第一是环路带宽自适应用状态机简单检测TED输出的滑动方差方差小于阈值时把BL·T从0.05降到0.01可以同时兼顾捕获速度和稳态抖动FPGA实现时就是多组Kp/Ki系数表切换时对NCO相位做连续性处理防止跳变。第二是滚降系数的选择根升余弦的滚降系数从0.25提高到0.5后多径引起的过零点偏移会减小因为频谱滚降区域占更大比例信号对抗ISI的余量更足代价是占用带宽变大适合带宽充裕的场合。第三是级联均衡在Gardner环后面挂一个自适应均衡器多径的固定ISI由均衡器消掉让定时环只负责相位对齐这种“先定时后均衡”的结构在实测中能比单环方案提高3dB以上的等效SNR。最后还有一个细节所有抗多径手段的验证都要跑完整链路不能只看定时抖动一项指标我这轮把误码率放进来后发现有些“抖动改善了”的配置误码率反而没变化因为真正限制性能的已经变成固定ISI了。以上措施是在我的两径模型下验证的真实信道多径条数更多、衰落随时间变化结论会有偏差但工程手段的方向一致。5.3 后续计划与个人验证心得下一轮测试我已经排上日程了一是把滚降系数从0.25换到0.5看定时环的耐受度能提高多少二是把两径扩张到三径、四径模拟更接近实际场景的频率选择性衰落三是考虑在多径模型基础上同时叠加残余载波频偏看看Gardner环在载波恢复之前的性能边界。每次测试我都会先把浮点模型跑一遍确定理论参考曲线再上FPGA定点否则很难判断结果是算法问题还是定点量化问题。个人体会很深的一点是FPGA里的时序同步模块最怕的不是算法复杂而是定点和环路参数没有量化的边界概念。多径测试能逼着人把所有边界都暴露出来这比单纯调好一个无多径场景的环路参数有价值得多。如果你也准备做类似测试我建议一开始就把多径时延、幅度、环路带宽、滚降系数四个参数做成交叉矩阵全部跑完再下结论单独一两个用例的波形说明不了任何设计优劣。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。