FPGA 多数率信号处理

文章来源:FPGA入门到精选

在无线通信、数字音频、雷达系统等领域,我们常面临这样的矛盾:信号采样时希望用高速率保证精度,处理时又需要低速率降低成本。

多速率信号处理(Multirate Signal Processing) 正是解决这一矛盾的“变速引擎”。它通过灵活调整信号采样率,实现了效率与性能的平衡。

单速率是指整个信号处理系统中只有一种数据速率;

多速率是指整个信号处理系统中存在多个数据速率,通过使用多速率信号处理可以节省存储空间、减少通信数据量、减少运算量、降低设计难度。

多速率信号处理在无线通信中的一个重要应用是软件无线电(SDR)中的数字上变频(DUC)和数字下变频(DDC)。

SDR面临相互矛盾的采样率需求:信号采样需要高采样率以降低ADC噪声并实现软件化处理,导致信号速率极高;信号处理与编码则期望低速率以聚焦有效频段;而DAC转换又需高采样率还原信号并提升信噪比。多速率信号处理技术通过插值和抽取,灵活实现信号速率转换,有效整合了这些需求。

一、核心原理:时域与频域的博弈

多速率信号处理的本质是通过 抽取(Decimation,降低采样率) 和 内插(Interpolation,提高采样率) 改变信号速率,辅以滤波器组消除混叠效应(Aliasing)或镜像干扰(Imaging)。

1、抽取(降采样)

输入信号数据每隔N-1个取一个,取出的数据依次排序,这个过程称作N倍抽取,采样率降低为原来的1/N。

将采样率降低整数倍(如2倍抽取),需先通过低通滤波器限制信号带宽(如Nyquist频率的1/2)。

为了避免抽取的信号出现频谱混叠,需要确保抽取后的采样率依旧满足Nyquist采样定理。

输入模拟信号经过高速ADC转换,会引入白噪声,所以一般需要在抽取前,加上抗混叠滤波。

图1:模拟信号.png图1:模拟信号.png

2、内插(升采样)

输入信号数据,在相邻数据点之间插入 I-1 个零值,再进行低通滤波,该过程称为 I 倍内插,采样率相应提高至原值的 I 倍。

只要低通滤波器(LPF)的通带覆盖信号的有效带宽,即使插值操作仅插入零值(而非实际采样点),仍可实现等效的 I 倍内插效果。

经过内插处理后的信号通过 DAC 输出时,引入的高频噪声将低于未内插的情况。

在相邻采样点间插入零值后,通过低通滤波器平滑波形(例如CD音频从44.1kHz升到176.4kHz以简化DAC设计)。

图2.png

3、非整数倍速率转换

在实际应用中经常遇到的速率转换不是整数倍关系。

可通过先进行 I 倍内插、再进行 D 倍抽取的方式,实现采样率为有理数比例(I/D) 的数据速率转换。

这时可共享一个低通滤波器(LPF),其截止频率取内插后信号与抽取前信号有效带宽的最小值即可。

图3.png

4、Noble恒等式

多级系统包括线性系统、内插器和抽取器时,允许交换这3个部分的顺序,显著降低计算复杂度(如多相结构)。

一个简单的多速率信号处理系统框图如下:

图4.png

例如,软件无线电中的数字下变频(DDC)链路由CIC滤波器、半带滤波器(HB)和FIR滤波器组成,逐级降低数据速率。

5、频谱混叠

假设某一个系统中,模拟信号只在0~2 kHz的频段内有信号,利用6 kHz的频率进行AD 采样,则采样后的信号没有频谱混叠,频谱周期为6 kHz,信号的频谱图如图6-5 (a) 所示。

图5.png

如果直接对6kHz的信号进行2倍抽取,则抽取后的信号频谱周期降为3kHz,频谱形状没有发生改变,但周期缩短了,导致信号频谱出现了混叠,如图6-5 (b)所示。

混叠的原因还可以从采样定理的角度来理解,抽取后的信号采样频率为3kHz,而原模拟信号的最高频率为2kHz,显然不满足无混叠抽样条件,出现频率混叠也就理所当然了。

所以为了无失真的恢复原来的模拟信号,需要在抽取之前通过“抗混叠滤波”即低通滤波,把信号的频带限制在抽样后频率的一半以上(满足抽样定理)。

二、matlab 仿真

MATLAB中实现抽取和内插操作很简单。

1、抽取

f = 100;        % 信号频率为100Hz

Fs = 10000;     % 采样频率为10KHz

%产生正弦波

t = 0 : 1 / Fs : 0.5;
c = 2 * pi * f * t;
si=sin(c);    
%抽取
D=8;       %抽取倍数
d2 = si(1 : D : length(t));  %抽取

2、内插

f = 100;        % 信号频率为100Hz

Fs = 10000;     % 采样频率为10KHz

% 产生正弦波

t = 0 : 1/Fs : 0.5;

c = 2 * pi * f * t;

si = sin(c); 

% 内插 

I = 8; % 内插倍数

Isi = zeros(1, length(si)*I); % 先构造全0序列

Isi(1 : I : length(Isi)) = si;  % 将源信号插入