• 正文
  • 相关推荐
申请入驻 产业图谱

FPGA实现QPSK调制解调(九)——基于Gardner算法的定时误差检测

04/23 08:58
416
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

数字通信系统中,定时同步是确保接收机正确解调的关键环节。

传统的模拟同步方法使用压控振荡器(VCO)调整采样时钟,但精度有限且难以集成。现代数字接收机采用全数字定时同步环路:ADC固定频率过采样,通过算法计算出"最佳采样时刻",再用插值滤波器重建信号。

Gardner算法,正是这个环路中的"眼睛"——它负责检测当前采样时刻与理想时刻的偏差。

Gardner算法:用对称性捕捉偏差

Gardner算法由Floyd M. Gardner于1986年提出,其核心思想极其优雅:利用数字信号波形的对称性,通过比较相邻符号的中间点与零 crossing,检测定时误差。

Gardner算法原理

定时误差计算公式为:

τ=y(k−1/2)×[y(k)−y(k−1)]

其中:

    y(k)是第k个符号在最佳判决点的采样值y(k−1)是前一个符号在最佳判决点的采样值y(k−1/2)是第k-1个符号与第k个符号中间点的采样值 对于QPSK信号,我们需要同时处理I、Q两路:
τ=I(k−1/2)×[I(k)−I(k−1)]+Q(k−1/2)×[Q(k)−Q(k−1)]

采样时刻控制

代码中使用interpolate_cnt计数器来区分不同的采样时刻:

always@(posedge i_clk)
begin
    if(i_rst == 1'b0)  
        interpolate_cnt <= 8'd0;
    else if((interpolate_cnt == 1) && i_interpolate_valid)  
        interpolate_cnt <= 8'd0;
    else if(i_interpolate_valid)  
        interpolate_cnt <= interpolate_cnt + 8'd1;
    else  
        interpolate_cnt <= interpolate_cnt;
end

每个符号周期采样2次(计数器在0、1之间循环)

    cnt=0 时:最佳判决点(符号峰值)
    cnt=1 时:符号中间点(用于误差检测) 这种每符号双采样结构是Gardner算法的标准配置,既保证了判决精度,又提供了误差检测所需的中间点信息。

数据流水线设计

为了同时获取当前采样、中间点采样和前一个判决点采样,代码设计了三级流水线:

interpolate_idata_dff1 <= i_interpolate_idata;
interpolate_idata_dff2 <= interpolate_idata_dff1;

这三个寄存器分别存储:

    i_interpolate_idata: 当前采样值 y(k)interpolate_idata_dff1: 中间点值 y(k−1/2)interpolate_idata_dff2: 前一个判决点值 y(k−1)

误差计算

Gardner算法需要乘法运算,但在硬件中直接使用乘法器资源消耗较大。本设计采用了一种优化方法——通过判断符号位的变化情况,将乘法简化为移位和加法操作。

case({i_interpolate_idata[19],interpolate_idata_dff2[19],
      i_interpolate_qdata[19],interpolate_qdata_dff2[19]})

通过判断符号位(最高位)来决定运算方式:

    符号位为1(负数):取反加一(补码求负)并左移一位(×2)符号位为0(正数):直接左移一位(×2)符号位变化为0:跳过该路计算

环路滤波器设计

定时同步是一个闭环控制系统环路滤波器的作用是平滑误差信号,产生稳定的小数间隔控制字:

// 一阶环路滤波器
// w(ms+1) = w(ms) + c1*(err(ms)-err(ms-1)) + c2*err(ms)
o_wn_data = o_wn_data + ({{2{error[21]}},error[21:8]}
                         -{{2{error_d1[21]}},error_d1[21:8]});

实现的是一个一阶数字滤波器,其中:

    c1 = 2^(-8),通过右移8位实现c2 ≈ 0,忽略二阶项以简化设计误差的符号位扩展({{2{error[21]}},error[21:8]})保证了有符号数运算的正确性

数据判决与同步

在最佳判决时刻,对I/Q两路数据进行硬判决:

o_sync_idata <= ~i_interpolate_idata[19];
o_sync_qdata <= ~i_interpolate_qdata[19];

判决门限设为0,因此直接取反符号位即可。这里假设数据采用补码表示,最高位为符号位(1表示负数,0表示正数)。

相关推荐