3、DFE(决策反馈均衡器)原理与设计

DFE这东西,说白了就是高速SerDes里用来“擦屁股”的。信号在信道里跑,遇到阻抗不连续、介质损耗,就会产生码间干扰(ISI)。前一个bit的能量拖到后一个bit上,眼图就闭上了。DFE就是把这个拖尾的能量给减掉。

我个人习惯把DFE理解成一个“有记忆的减法器”。它记住之前发过什么bit,然后根据这些bit来预测当前bit会受到多大的干扰,最后把这个干扰减掉。嗯,就这么简单。

3.1 DFE工作原理

DFE的核心思想是:既然我知道之前发了什么,我就能算出它对当前bit的影响。你想想看,信道是线性的,前一个bit的拖尾波形是固定的。那我只要知道前一个bit是1还是0,就能知道它现在还剩多少能量在干扰我。

数学上,DFE的输出可以写成:

y(n) = x(n) - Σ w(k) * d(n-k)

这里:

  • x(n) 是当前接收到的模拟信号
  • d(n-k) 是之前判决出的bit(1或-1)
  • w(k) 是第k个抽头的系数
  • y(n) 是均衡后的信号,送给 slicer 做判决

我在项目中遇到过一种情况:信道很长,ISI拖了七八个UI。这时候DFE的抽头数就得跟上。少一个抽头,眼图就多一分闭合的风险。所以抽头数量不是拍脑袋定的,得根据信道响应来算。

关键点:DFE是非线性的。因为它用到了判决后的数字信号做反馈。这意味着它不会放大噪声——这是它比线性均衡器(比如CTLE)强的地方。

3.2 抽头系数更新算法

抽头系数怎么定?不能靠猜。实际芯片里,DFE的系数是自适应更新的。最常用的算法是LMS(最小均方)算法。

LMS的思路很直观:

  1. 先算误差:e(n) = d(n) - y(n),也就是判决后的bit和均衡后的信号之间的差。
  2. 然后更新系数:w(k) = w(k) + μ * e(n) * d(n-k)

这里的 μ 是步长,控制收敛速度。步长太大,系数会震荡;步长太小,收敛太慢。我建议刚开始用 μ = 2^(-N) 这种2的幂次,硬件实现起来最省资源。

举个例子,一个3抽头的DFE,LMS更新伪代码:

// 初始化
w[0] = 0.1; w[1] = 0.05; w[2] = 0.02;
mu = 1/128;

// 每个UI更新一次
for each clock cycle:
    // 计算均衡后的值
    y = x - (w[0]*d_prev1 + w[1]*d_prev2 + w[2]*d_prev3);
    
    // 判决
    d = (y > 0) ? 1 : -1;
    
    // 计算误差
    e = d - y;
    
    // 更新系数
    w[0] = w[0] + mu * e * d_prev1;
    w[1] = w[1] + mu * e * d_prev2;
    w[2] = w[2] + mu * e * d_prev3;
    
    // 移位
    d_prev3 = d_prev2;
    d_prev2 = d_prev1;
    d_prev1 = d;

实战技巧:我曾经在28nm工艺上做过一个DFE,发现LMS收敛后系数会一直抖动。后来加了泄漏因子(leaky factor),让系数缓慢衰减到0。这样既保证了跟踪能力,又避免了系数漂移。

3.3 高速SerDes中的DFE实现

到了高速SerDes(比如28Gbps以上),DFE的实现就没那么简单了。为什么?因为时序。一个UI只有35ps左右,DFE的反馈环路必须在一个UI内完成:接收信号 → 减去反馈 → 判决 → 更新系数。这太难了。

我见过几种工程上的折中方案:

  • 半速率架构:把数据分成奇偶两路,每路工作在1/2速率。这样每个路径有2个UI的时间做处理。代价是面积翻倍。
  • 推测式DFE(Speculative DFE):提前算出所有可能的反馈值,然后根据实际判决结果选一个。比如1抽头DFE,提前算好“如果前一个bit是1,当前值是多少;如果是-1,当前值是多少”。这样反馈环路就变成了一个MUX选择,快很多。
  • 环路展开(Loop Unrolling):把多个UI的反馈合并成一个组合逻辑。比如2抽头DFE,可以展开成4种情况。面积大,但时序好。

下面这张图展示了典型的4抽头DFE在SerDes中的位置:

典型4抽头DFE在SerDes接收链路中的位置 模拟输入 CTLE + DFE 均衡 y = x - Σw*d Slicer 数字输出 Dout LMS 系数更新 抽头延迟链 D D D D

注意:DFE的抽头系数不是越大越好。抽头多了,功耗和面积都上去了,而且收敛可能变慢。我曾经在一个56Gbps PAM4项目中,发现4抽头DFE就够用了,硬加到6抽头反而因为系数噪声导致误码率上升。所以,够用就好

3.4 工程实现中的几个坑

最后聊几个我踩过的坑:

  • 初始系数怎么设? 全0肯定不行,收敛太慢。我一般先跑一个信道仿真,把抽头系数初值设成信道响应的采样值。这样LMS只需要微调,收敛快很多。
  • 系数精度多少位? 6-8位就够了。太多位浪费面积,太少位收敛不到最优值。我习惯用7位有符号数,1位符号位,6位小数。
  • 要不要做系数冻结? 要。收敛完成后,把系数冻结住,避免持续抖动。等信道条件变化了再解冻。这个机制在PCIe Gen5/6里很常见。

嗯,DFE这部分内容就这些。说白了就是“用过去的bit,算现在的干扰,然后减掉它”。原理不复杂,但工程实现上处处是细节。希望这些经验能帮你少走弯路。


公众号:蓝海资料掘金营,微信deep3321