4、数字上变频(DUC):内插滤波、CIC补偿滤波器、HB半带滤波器、频谱搬移

数字上变频,简称DUC,是发射链路里绕不开的一环。说白了,就是把基带的低速数字信号,一路折腾成高速的中频或射频信号,然后送出去。我做了这么多年通信芯片,DUC这块踩过的坑真不少,今天跟你好好聊聊。

4.1 内插滤波:为什么要插值?

基带信号速率低,比如几兆、几十兆。但DAC(数模转换器)通常喜欢工作在更高频率,比如几百兆。怎么办?插值。

内插,就是在两个原始采样点之间插入零值。比如2倍内插,每两个点中间塞一个0。速率直接翻倍。但问题来了——插零会引入镜像频谱。你想想看,原始频谱在低频,插值后高频区域会多出一堆“鬼影”。

所以,内插之后必须跟一个低通滤波器,把这些镜像干掉。这个滤波器就叫内插滤波器。我习惯把内插和滤波打包看成一个整体,叫“内插滤波级”。

核心要点:内插本身不改变频谱形状,但会引入镜像。滤波器的任务就是把这些镜像滤干净。

4.2 CIC补偿滤波器:省资源的利器

CIC滤波器,全称级联积分梳状滤波器。这玩意儿有个绝活——不需要乘法器,只用加法器和延迟器。在FPGA或ASIC里,乘法器是稀缺资源,加法器管够。所以CIC特别适合做高速率、大倍数的内插。

但CIC有个毛病:通带衰减太厉害。你想想看,信号经过CIC后,高频分量会被压下去,幅度响应不平坦。这时候就需要一个补偿滤波器,把通带拉平。

我在项目中遇到过这种情况:用CIC做8倍内插,结果信号带宽边缘掉了3个dB。后来加了一级FIR补偿滤波器,才把通带纹波控制在0.1dB以内。

个人经验:CIC补偿滤波器通常放在CIC之前或之后,具体看系统架构。我建议放在CIC之前,因为补偿滤波器的阶数可以做得更低,节省资源。

CIC的传递函数长这样:

H(z) = [ (1 - z^(-RM)) / (1 - z^(-1)) ]^N

其中R是内插倍数,M是差分延迟(通常取1或2),N是级联级数。级数越多,阻带衰减越好,但通带衰减也更严重。

4.3 HB半带滤波器:效率之王

半带滤波器,简称HB。这玩意儿在DUC里出场率极高,因为它有一半的系数是0。你想想看,一半系数是0,意味着乘法运算量直接减半。在芯片里,这就是省面积、省功耗。

HB滤波器的频率响应有个特点:通带和阻带关于π/2对称。也就是说,它的3dB截止频率正好在fs/4处。所以HB天然适合做2倍内插或2倍抽取。

我记得有一次做WCDMA的DUC,用了三级HB级联,实现了8倍内插。每一级HB的系数都只有7~11个非零值,整个滤波器组占用的乘法器资源还不到一个普通FIR的一半。

注意:HB滤波器只能做2倍内插。如果你想做3倍、5倍这种非2的幂次倍内插,得用其他滤波器,比如FIR或CIC。

HB滤波器的系数设计也有讲究。通常用窗函数法或Parks-McClellan算法。我个人习惯用等波纹法,因为通带纹波和阻带衰减可以精确控制。

4.4 频谱搬移:从基带到中频

信号经过内插滤波后,速率上去了,但频谱还在基带。要发射出去,得把频谱搬到中频或射频。这一步叫频谱搬移,也叫数字混频。

做法很简单:把基带信号乘以一个数字本振。本振频率就是你想搬移的目标频率。数学上就是:

s_out[n] = s_in[n] * cos(2π * f_c / f_s * n)

其中f_c是载波频率,f_s是采样率。cos和sin来自NCO(数控振荡器)。NCO通常用CORDIC算法或查找表实现。

这里有个坑:混频后会产生两个频率分量,一个是f_c,一个是-f_c。我们只想要正频率那个,负频率那个得用滤波器干掉。所以混频之后通常还要跟一个低通或带通滤波器。

我曾经在某个项目里,因为NCO的相位截断误差没处理好,导致混频后的信号出现了杂散。后来把NCO的相位累加器位数从16位加到24位,杂散才压下去。

4.5 完整的DUC链路

一个典型的DUC链路长这样:

  1. 基带输入:低速I/Q数据
  2. CIC补偿滤波器:预补偿CIC的通带衰减
  3. CIC内插滤波器:大倍数内插,比如8倍、16倍
  4. HB半带滤波器级联:逐级2倍内插,把速率提到目标值
  5. 频谱搬移:乘以NCO,搬到中频
  6. 输出到DAC:高速数据流

这个链路里,每一级都有讲究。CIC负责粗调,HB负责精调,混频负责搬移。我建议你在设计时,先确定总内插倍数,再拆分成CIC和HB的组合。比如总内插32倍,可以拆成CIC 8倍 + HB 2倍 + HB 2倍。

避坑指南:我曾经在CIC和HB之间忘记加增益调整,结果信号幅度一路衰减,到混频时信噪比已经惨不忍睹。记住,每一级滤波器都有增益,要提前算好并做归一化。

4.6 资源与性能的权衡

做芯片设计,永远在资源和性能之间找平衡。DUC也不例外。

滤波器类型 资源消耗 通带性能 适用场景
CIC 极低(无乘法器) 通带衰减大 大倍数内插
HB 低(一半系数为0) 2倍内插级联
普通FIR 最好 小倍数或补偿

我个人习惯:能用CIC的地方绝不用FIR,能用HB的地方绝不用普通FIR。只有在通带要求极其苛刻时,才上普通FIR。

小技巧:如果你用FPGA实现DUC,记得把CIC的积分器和梳状器的位宽留足。CIC内部位宽会增长,截位不当会导致信号失真。我一般会多留4~6个bit的余量。

好了,DUC这块就聊到这儿。下一章我们讲数字下变频(DDC),那是接收链路的反向操作,同样精彩。