文章灵感来源于MATLAB官方免费教程:HDL Coder Self-Guided Tutorial
考虑到MATLAB官网的英文看着慢,再加上视频讲解老印浓浓的咖喱味,我决定记录利用MATLAB&Simulink&SystemGenerator进行FPGA数字信号处理的学习过程。
在进行数字信号处理的算法验证阶段,主要是通过MATLAB进行算法设计,然后用Simulink模块化进行算法验证。
- % Setup
- clear; clc; close all;
- % Create pulse to detect
- rng('default');
- PulseLen = 64;
- theta = rand(PulseLen,1);
- pulse = exp(1i*2*pi*theta);
- % Insert pulse to Tx signal
- rng('shuffle');
- TxLen = 5000;
- PulseLoc = randi(TxLen-PulseLen*2);
- TxSignal = zeros(TxLen,1);
- TxSignal(PulseLoc:PulseLoc+PulseLen-1) = pulse;
- % Create Rx signal by adding noise
- Noise = complex(randn(TxLen,1),randn(TxLen,1));
- RxSignal = TxSignal + Noise;
- % Scale Rx signal to +/- one
- scale1 = max([abs(real(RxSignal)); abs(imag(RxSignal))]);
- RxSignal = RxSignal/scale1;
这段代码主要执行了以下操作:
代码创建完毕后生成的RxSignal即是需要进行滤波处理的信号。
- % Create matched filter coefficients
- CorrFilter = conj(flip(pulse))/PulseLen;
- % Correlate Rx signal against matched filter
- FilterOut = filter(CorrFilter,1,RxSignal);
- % Find peak magnitude & location
- [peak, location] = max(abs(FilterOut));
- % Print results
- figure(1)
- subplot(311); plot(real(TxSignal)); title('Tx Signal (real)');
- subplot(312); plot(real(RxSignal)); title('Rx Signal (real)');
- t = 1:length(FilterOut);
- str = sprintf('Peak found at %d with a value of %.3d',location,peak);
- subplot(313); plot(t,abs(FilterOut),location,peak,'o'); title(str);
这段代码主要执行了以下操作:
创建匹配滤波器系数:创建一个与脉冲信号(pulse)匹配的滤波器。匹配滤波器在接收端用于检测信号中的特定序列或模式。CorrFilter 是通过对脉冲信号取共轭并翻转后除以长度(PulseLen)得到的。
函数对 Rx 信号和匹配滤波器进行相关运算,以检测信号中的脉冲。FilterOut 存储了相关运算的结果。
查找峰值幅度和位置:使用 max 函数找到 FilterOut 中的峰值及其位置。peak 存储了找到的峰值的幅度,location 存储了其位置。
打印结果:创建一个包含三个子图的图形窗口,分别显示 Tx 信号的实部、Rx 信号的实部以及滤波器输出的幅度。在第三个子图中,将峰值和其位置用圆圈标出,并在标题中显示峰值的位置和幅度。
- WindowLen = 11;
- MidIdx = ceil(WindowLen/2);
- threshold = 0.03;
- % Compute magnitude squared to avoid sqrt operation
- MagSqOut = abs(FilterOut).^2;
- % Sliding window operation
- for n = 1:length(FilterOut)-WindowLen
-
- % Compare each value in the window to the middle sample via subtraction
- DataBuff = MagSqOut(n:n+WindowLen-1);
- MidSample = DataBuff(MidIdx);
- CompareOut = DataBuff - MidSample; % this is a vector
-
- % if all values in the result are negative and the middle sample is
- % greater than a threshold, it is a local max
- if all(CompareOut <= 0) && (MidSample > threshold)
- peak_2 = MidSample;
- location_2 = n + (MidIdx-1);
- end
- end
这段代码主要执行了以下操作:
设置窗口长度为 11:这个窗口长度用于滑动窗口操作,以便对滤波器输出进行局部最大值的检测。
计算窗口的中间索引:用于找到窗口中间的样本位置。
设置阈值为 0.03:该阈值用于判断窗口中间的样本是否为局部最大值。
在滤波器输出中,可能存在一些噪声或干扰,导致局部最大值的检测不够准确。通过设置阈值,可以过滤掉那些相对较小的局部峰值,只保留那些显著的峰值,从而提高检测的准确性。
换句话说,阈值充当了一个过滤器,确保只有满足一定幅度要求的峰值才被认为是有效的局部最大值。
对滤波器输出的幅度进行平方,以避免每次比较时都需要进行开方操作,提高运算效率。
通过一个 for 循环,对滤波器输出进行滑动窗口操作,以便检测局部最大值。
将窗口中的每个值与中间样本进行比较:将窗口中的数据与中间样本相减,用于判断是否为局部最大值。
如果结果中的所有值都为负且中间样本大于阈值,则中间样本为局部最大值
在运行MATLAB参考算法之后生成的工作区包含需要进行处理的信号等各个参量。

同时还会生成脉冲信号的实部,添加了噪声的脉冲信号实部以及滤波器的输出信号:

在MATLAB滤波算法中,关键算法匹配滤波器上。在 MATLAB 中,filter 函数用于对输入信号进行滤波操作。它可以应用各种数字滤波器,包括移动平均滤波器、低通滤波器、高通滤波器等。
y = filter(b, a, x)
其中:
b 是滤波器的分子系数(也称为 FIR 滤波器的系数)。a 是滤波器的分母系数(也称为 IIR 滤波器的系数),如果省略,则默认为 1,表示使用的是 FIR 滤波器。x 是输入信号。函数返回滤波后的输出信号 y。
filter 函数通过对输入信号 x 与滤波器的系数 b 和 a 进行卷积操作来计算输出信号。具体来说,对于 FIR 滤波器,输出信号的每个样本都是输入信号在滤波器的系数上的加权和。