从零开始利用MATLAB进行FPGA设计(一):建立脉冲检测模型的Simulink模型1

文章灵感来源于MATLAB官方免费教程:HDL Coder Self-Guided Tutorial

考虑到MATLAB官网的英文看着慢,再加上视频讲解老印浓浓的咖喱味,我决定记录利用MATLAB&Simulink&SystemGenerator进行FPGA数字信号处理的学习过程。

在进行数字信号处理的算法验证阶段,主要是通过MATLAB进行算法设计,然后用Simulink模块化进行算法验证。

1.MATLAB参考算法

1.1创建输入模拟

% 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;

这段代码主要执行了以下操作:

  1. 清空 MATLAB 工作区,关闭所有图形窗口,清空命令窗口。
  2. 创建一个长度为 64 的脉冲信号(pulse),信号的相位由随机生成的角度(theta)决定。
  3. 在长度为 5000 的 Tx 信号中随机选择一个位置,并将上面创建的脉冲信号插入到该位置。
  4. 为 Rx 信号添加了复数形式的高斯白噪声(Noise)。
  5. 将 Rx 信号进行归一化,使其最大幅度为 1。

代码创建完毕后生成的RxSignal即是需要进行滤波处理的信号。

1.2通过滤波算法进行滤波(黄金准则)

% 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);

这段代码主要执行了以下操作:

  1. 创建匹配滤波器系数:创建一个与脉冲信号(pulse)匹配的滤波器。匹配滤波器在接收端用于检测信号中的特定序列或模式。CorrFilter 是通过对脉冲信号取共轭并翻转后除以长度(PulseLen)得到的。

  2. 函数对 Rx 信号和匹配滤波器进行相关运算,以检测信号中的脉冲。FilterOut 存储了相关运算的结果。

  3. 查找峰值幅度和位置:使用 max 函数找到 FilterOut 中的峰值及其位置。peak 存储了找到的峰值的幅度,location 存储了其位置。

  4. 打印结果:创建一个包含三个子图的图形窗口,分别显示 Tx 信号的实部、Rx 信号的实部以及滤波器输出的幅度。在第三个子图中,将峰值和其位置用圆圈标出,并在标题中显示峰值的位置和幅度。

1.3硬件友好的峰值查找算法

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

这段代码主要执行了以下操作:

  1. 设置窗口长度为 11:这个窗口长度用于滑动窗口操作,以便对滤波器输出进行局部最大值的检测。

  2. 计算窗口的中间索引:用于找到窗口中间的样本位置。

  3. 设置阈值为 0.03:该阈值用于判断窗口中间的样本是否为局部最大值。

    在滤波器输出中,可能存在一些噪声或干扰,导致局部最大值的检测不够准确。通过设置阈值,可以过滤掉那些相对较小的局部峰值,只保留那些显著的峰值,从而提高检测的准确性。

    换句话说,阈值充当了一个过滤器,确保只有满足一定幅度要求的峰值才被认为是有效的局部最大值。

  4. 对滤波器输出的幅度进行平方,以避免每次比较时都需要进行开方操作,提高运算效率。

  5. 通过一个 for 循环,对滤波器输出进行滑动窗口操作,以便检测局部最大值。

  6. 将窗口中的每个值与中间样本进行比较:将窗口中的数据与中间样本相减,用于判断是否为局部最大值。

  7.  如果结果中的所有值都为负且中间样本大于阈值,则中间样本为局部最大值

在运行MATLAB参考算法之后生成的工作区包含需要进行处理的信号等各个参量。

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

2.匹配滤波器

在MATLAB滤波算法中,关键算法匹配滤波器上。在 MATLAB 中,filter 函数用于对输入信号进行滤波操作。它可以应用各种数字滤波器,包括移动平均滤波器、低通滤波器、高通滤波器等。

y = filter(b, a, x)

其中:

  • b 是滤波器的分子系数(也称为 FIR 滤波器的系数)。
  • a 是滤波器的分母系数(也称为 IIR 滤波器的系数),如果省略,则默认为 1,表示使用的是 FIR 滤波器。
  • x 是输入信号。

函数返回滤波后的输出信号 y

filter 函数通过对输入信号 x 与滤波器的系数 ba 进行卷积操作来计算输出信号。具体来说,对于 FIR 滤波器,输出信号的每个样本都是输入信号在滤波器的系数上的加权和。