一、基于Simulink产生HDL代码并生成Vivado工程
1、功能描述
2、MATLAB 标准的匹配滤波算法
3、FPGA上实现算法
3.1 软件要求
3.2 实现步骤
3.2.1 创建算法的Simulink模型
3.2.2 实现硬件结构
3.2.3 转换设计为定点
3.2.4 生成和综合HDL代码
一、基于Simulink产生HDL代码并生成
Vivado工程
1、功能描述
在这个教程中,首先给出一个基于MATLAB的脉冲检测算法,该算法使用一个匹配滤波器从接收信号
中检测一个已知的波形,并且获取波形的峰值。该算法普遍应用于雷达或者无线通信系统中。
2、MATLAB 标准的匹配滤波算法
% Setup
clear; clc; close all;
% Create pulse to detect
rng('default'); % rng('default') 将 rand、
randi 和 randn 使用的随机数生成器的设置重置为其默认值。这样,会生成相同的随机数,就好像您重新
启动了 MATLAB。默认设置是种子为 0 的梅森旋转生成器。
PulseLen = 64;
theta = rand(PulseLen,1); % X = rand 返回一个在区间
(0,1) 内均匀分布的随机数
pulse = exp(1i*2*pi*theta); % Y = exp(X) 为数组 X 中的每个
元素返回指数 ex。
% Insert pulse to Tx signal
rng('shuffle'); % rng('shuffle') 根据当前时间
为随机数生成器提供种子。
TxLen = 5000;
PulseLoc = randi(TxLen-PulseLen*2); % X = randi(imax) 返回一个介于
1 和 imax 之间的伪随机整数标量。
TxSignal = zeros(TxLen,1);
TxSignal(PulseLoc:PulseLoc+PulseLen-1) = pulse; % 插入脉冲
% Create Rx signal by adding noise
Noise = complex(randn(TxLen,1),randn(TxLen,1)); % z = complex(a,b) 通过两个实
数输入创建一个复数输出 z,这样 z = a + bi。
RxSignal = TxSignal + Noise;
% Scale Rx signal to +/- one
scale1 = max([abs(real(RxSignal)); abs(imag(RxSignal))]);
RxSignal = RxSignal/scale1;
% Create matched filter coefficients
CorrFilter = conj(flip(pulse))/PulseLen; % Zc = conj(Z) 返回 Z 中每个元
素的复共轭。频域取共轭相当于时域共轭对称部分不变,共轭反对称部分取反(也就是乘以-1)
% Correlate Rx signal against matched filter
FilterOut = filter(CorrFilter,1,RxSignal); % y = filter(b,a,x) 使用由分子
和分母系数 b 和 a 定义的有理传递函数 对输入数据 x 进行滤波。
% 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);
程序运行结果如下图:
TxSignal:原始的脉冲信号;
RxSignal:叠加了高斯白噪声后的信号;
FilterOut:匹配滤波后信号输出。
3、FPGA上实现算法
3.1 软件要求
MATLAB® (R2019b)
Simulink®
Fixed-Point Designer
MATLAB Coder
HDL Coder
Signal Processing Toolbox
DSP System Toolbox
Xilinx® Vivado® 2017.4(其它版本也可,只是综合结果不同)
3.2 实现步骤
3.2.1 创建算法的Simulink模型
1. 运行第二步的程序初始化该步骤需要的参数;
2. 创建一个Simulink模型命名为pulse_detector_v1.slx;
3. 添加一个Signal From Workspace 模块并在信号栏填写RxSignal表示从MATLAB工作空间中获得
该信号。
4. 使用 Discrete FIR Filter模块实现匹配滤波函数以步骤2的匹配滤波系数CorrFilter作为该模块的
滤波系数
5. 命名滤波器的输出信号为filter_out并且使能信号的数据日志记录
6. 仿真停止时间设置为SimTime(SimTime = length(RxSignal) + WindowLen)
7. 编写Simulink测试脚本pulse_detector_v1_tb.mlx并运行到第16行,验证Simulink滤波器的输
出和第2步中输出之间的误差
% Simulate model and compare results to reference
if iscolumn(CorrFilter) % 确定输入是否为列向量
CorrFilter = transpose(CorrFilter); % need row vector for filter block
end
SimTime = length(RxSignal) + WindowLen;
% Simulate model
slout = sim('pulse_detector_v1'); % simOut = sim(model) 使用现有模型配置
参数对指定模型进行仿真,并将结果返回为 Simulink.SimulationOutput 对象
% Correlation filter output
FilterOutSL = getLogged(slout,'filter_out');
compareData(real(FilterOut),real(FilterOutSL),{2 3 1},'ML vs SL correlator
output (re)');
compareData(imag(FilterOut),imag(FilterOutSL),{2 3 2},'ML vs SL correlator
output (im)');
% 运行到此处
% Magnitude squared output
MagSqSL = getLogged(slout,'mag_sq_out'); % Get the object a signal
interface element
compareData(MagSqOut,MagSqSL,{2 3 3},'ML vs SL mag-squared output');
% Peak value
MidSampleSL = getLogged(slout,'mid_sample');
Detected = getLogged(slout,'detected');
PeakSL = MidSampleSL(Detected>0);
fprintf('\nPeak location = %d, magnitude = %.3d using global
max\n',location,peak);
fprintf('Peak location = %d, mag-squared = %.3d using local
max\n',location_2,peak_2);
fprintf('Peak mag-squared from Simulink = %.3d, error =
%.3d\n',PeakSL,abs(peak_2-PeakSL));
%
% Copyright 2020 The MathWorks, Inc.
%
function signal_val = getLogged(simout_obj,signal_name)
logsout = simout_obj.logsout;
if isempty(logsout)
error('No logged signal found. Make sure ''%s'' is logged in the
model',...
signal_name);
end
sig = logsout.getElement(signal_name);
if isempty(sig)
error('Signal ''%s'' not found. Make sure it is logged and named
correctly.',...
signal_name);
end
signal_val = squeeze(sig.Values.Data);
end
8. 回顾第2步中硬件友好的峰值检测算法,在滤波器模块的输出,调用下列模块实现求幅度的平方
输出输入的实部和虚部
实部和虚部分别求平方
求和模块进行实部和虚部求和得到信号的幅度的平方。
9. 封装第8步的模块为一个子系统并命名为Compute Power标记子系统的输出为mag_sq_out。
10. 显示信号的维度和信号的数据类型
11. 连接mag_sq_out到一个Tapped Delay模块作为滑动窗口的缓冲。设置延时的长度为滑动窗口的
长度WindowLen