VIVADO IP核之FIR抽取器多相滤波仿真

VIVADO IP核之FIR抽取器多相滤波仿真(含有与MATLAB仿真数据的对比)

目录

前言

一、滤波器系数生成

二、用MATLAB生成仿真数据

[三、VIVADO FIR抽取多相滤波器使用](#三、VIVADO FIR抽取多相滤波器使用)

[四、VIVADO FIR抽取多相滤波器仿真](#四、VIVADO FIR抽取多相滤波器仿真)

五、VIVADO工程下载

总结


前言

关于FIR低通滤波器和多相滤波插值器的使用,我之前的文章已经介绍过了,本文将继续深入介绍FIR抽取器多相滤波的使用方法,并将FIR抽取多相滤波的结果与MATLAB仿真计算的结果比较,验证了FIR抽取器多相滤波使用正确。


++提示:以下是本篇文章正文内容,欢迎各位阅读,转载请附上链接。++

一、滤波器系数生成

仿真假设有一个信号由两个正弦波叠加而成,分别是幅值为1,频率为5MHz,初相为0的正弦波和幅值为1,频率为15MHz,初相为0的正弦波。用120MHz的采样率对其进行采样,那么可以得到一个信号速率为120MSPS,包含频率为5MHz和15MHz正弦波的信号,接下来我们分别用MATLAB和FIR ip核对其进行4抽取多相滤波,滤波器的通带截止频率为10MHz,那么便可以得到一个信号速率为30MSPS,频率为5MHz的正弦波。

滤波器设计如下,抽取之前速率为120M,所以这里滤波器的采样频率是120MHz,而不是30MHz。设计的滤波器为51阶,那么有52个系数,便于4抽取多相滤波。

关于滤波器系数的量化成16bit以及生成coe文件可以参考我的另外一篇博客VIVADO IP核之FIR低通滤波仿真(含滤波器群延时仿真)_vivado fir滤波器-CSDN博客,里面有详细的介绍,本文就不再赘述。

二、用MATLAB生成仿真数据

运行以下代码即可生成vivado仿真所需要的仿真数据data_decimation.txt。

Matlab 复制代码
rng default;
clc; 
clear;
close all;

fs =  120e6;     % 采样频率 120MHz
K = 1024;       % 快拍个数
t = 0:1/fs:(K-1)/fs;
f1 = 5e6;
f2 = 15e6;
x = cos(2*pi*f1*t) + cos(2*pi*f2*t);

h = fopen('data_decimation.txt','w');
for i=1:length(x)
    result= fi(x(i), 1, 16, 9).bin;
    fprintf(h,'%s\n',result);
end
fclose(h);

figure(1);
plot(x(1:60));
grid on;
figure(2);
signal_frequencyspectrum(x,fs);
grid on;
ylim([-90 0]);

lowpass_Fs=fs;            % 低通滤波器的采样频率
lowpass_Fpass=10000000;   % 低通滤波器的通带截止频率
lowpass_Fstop=14000000;   % 低通滤波器的阻带起始频率
% 下一行的lowpass是用fdatool设计的滤波器保存为matlab code自己修改了一下
[lowpass_b,lowpass_a] = tf(lowpass(lowpass_Fs,lowpass_Fpass,lowpass_Fstop));% 得到滤波器系数

y=conv(x,lowpass_b);
x_MLPF=y(2:4:end);
% lowpass_b1=lowpass_b(1:4:end);
% lowpass_b2=lowpass_b(2:4:end);
% lowpass_b3=lowpass_b(3:4:end);
% lowpass_b4=lowpass_b(4:4:end);
% 
% x1=x(1:4:end);
% x=[0 x];
% x2=x(1:4:end);
% x=[0 x];
% x3=x(1:4:end);
% x=[0 x];
% x4=x(1:4:end);
% 
% 
% x_MLPF1=conv(x1,lowpass_b1);
% x_MLPF2=conv(x2,lowpass_b2);
% x_MLPF3=conv(x3,lowpass_b3);
% x_MLPF4=conv(x4,lowpass_b4);
% 
% x_MLPF=[x_MLPF1 0]+x_MLPF2+x_MLPF3+x_MLPF4;

figure(3);
plot(x_MLPF(1:60));
grid on;
figure(4);
signal_frequencyspectrum(x_MLPF(ceil((length(lowpass_b)-1)/2)+1:end-floor((length(lowpass_b)-1)/2)),fs/4);
grid on;
ylim([-90 0]);
Matlab 复制代码
function Hd = lowpass(lowpass_Fs,lowpass_Fpass,lowpass_Fstop)
%LPF 返回离散时间滤波器对象。

% MATLAB Code
% Generated by MATLAB(R) 23.2 and Signal Processing Toolbox 23.2.
% Generated on: 02-Aug-2024 20:04:40

% Equiripple Lowpass filter designed using the FIRPM function.

% All frequency values are in Hz.
Fs = lowpass_Fs;  % Sampling Frequency

Fpass = lowpass_Fpass;   % Passband Frequency
Fstop = lowpass_Fstop;   % Stopband Frequency
Dpass = 0.057501127785;   % Passband Ripple
Dstop = 0.0031622776602;  % Stopband Attenuation
dens  = 20;               % Density Factor

% Calculate the order from the parameters using FIRPMORD.
[N, Fo, Ao, W] = firpmord([Fpass, Fstop]/(Fs/2), [1 0], [Dpass, Dstop]);

% Calculate the coefficients using the FIRPM function.
b  = firpm(N, Fo, Ao, W, {dens});
Hd = dfilt.dffir(b);

% [EOF]

MATLAB原始信号如下图所示:

低通滤波4抽取后的信号为(可见FIR滤波器有群延时):

三、VIVADO FIR抽取多相滤波器使用

在vivado中搜索FIR滤波器IP核并点进去设置它。滤波器命名为FIR_polyphase_LPF,导入第一步MATLAB生成的滤波器系数文件。Filter type 选择抽取,抽取因子设置为4。

输入信号采样速率设置为120MHz,时钟频率设置为120MHz,这样抽取前每个输入持续1个时钟周期,4抽取后就变成了每4个时钟出1个数据。

滤波器系数设置为16位有符号数,输入数据也为16位有符号数,输入数据的小数位数设置为9,这是因为第二步中MATLAB量化的输入数据含有9位小数。然后点击左边的Freq.Response就能看见滤波器的幅度响应。

滤波抽取调用FIR多相抽取滤波比我们先调用FIR低通滤波后再抽取节约资源的多。

四、VIVADO FIR抽取多相滤波器仿真

在工程中建立一个名为FIR_polyphase_LPF_test的tb.v文件。其中$readmemb("data_decimation.txt", signal)用于从文本中读取二进制数据赋值给signal。

Matlab 复制代码
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/08/06 15:36:14
// Design Name: 
// Module Name: FIR_polyphase_LPF_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

module FIR_polyphase_LPF_test();

reg clk=1;
parameter PERIOD=2;
initial
begin
    forever #(PERIOD/2)  clk=~clk;
end

reg s_axis_data_tvalid=0;
wire s_axis_data_tready;
reg [15:0] s_axis_data_tdata=0;
wire m_axis_data_tvalid;
wire [39:0] m_axis_data_tdata;

integer i=0;
reg [15:0] signal[1023:0];

initial
begin
    $readmemb("data_decimation.txt", signal);//从data.txt中读入采样数据
    #(PERIOD*5)
    forever 
    begin
        @(negedge clk) 
        begin
            if(i<1024) 
                begin
                    s_axis_data_tvalid<=1;
                    s_axis_data_tdata <= signal[i];
                    i <= i + 1;
                end
            else
                begin
                    s_axis_data_tvalid<=0;
                    s_axis_data_tdata <=0;
                end
        end
    end 
end

integer dout_file;
initial 
begin
    dout_file=$fopen("E:/play_vivado/FIR_polyphase_decimation_test/Readme/m_axis_data_tdata.txt"); //打开所创建的文件,修改为自己想存储的位置
    if(dout_file == 0)
    begin 
        $display ("can not open the file!"); //创建文件失败,显示can not open the file!
        $stop;
    end
end

initial
begin
    forever
    begin
        @(posedge clk) 
        begin
            if(m_axis_data_tvalid)
            $fdisplay(dout_file,"%d",$signed(m_axis_data_tdata)); //保存有符号数据
        end
    end
end

FIR_polyphase_LPF u_FIR_polyphase_LPF (
  .aclk(clk),                               // input wire aclk
  .s_axis_data_tvalid(s_axis_data_tvalid),  // input wire s_axis_data_tvalid
  .s_axis_data_tready(s_axis_data_tready),  // output wire s_axis_data_tready
  .s_axis_data_tdata(s_axis_data_tdata),    // input wire [15 : 0] s_axis_data_tdata
  .m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata)    // output wire [39 : 0] m_axis_data_tdata
);

endmodule

接下来将第二步生成的仿真数据保存到...\FIR_polyphase_decimation_test\FIR_polyphase_decimation_test.sim\sim_1\behav\xsim文件夹下:

然后点击run simulation。将s_axis_data_tdata的数据格式设置为定点有符号数,小数位数为9位。将m_axis_data_tdata_real的数据格式设置为定点有符号数,小数位数为26位。然后就能看见输入的数据依次为2.0,1.6738,0.8652...,和MATLAB生成的信号数据是对的上的。滤波后的数据依次为0.0116,-0.0245,-0.0466,...,和MATLAB滤波后的信号数据也是对的上的。

这里注意一下FIR 抽取多相滤波IP核是从第二个数据开始抽取的。

将输入输出设置为波形显示如下:

可知FIR 抽取多相滤波IP核既完成了滤波,又完成了抽取操作,抽取后是每4个clk出一个数据。

五、VIVADO工程下载

https://download.csdn.net/download/m0_66360845/89797080https://download.csdn.net/download/m0_66360845/89797080


总结

本文讲解了VIVADO中FIR抽取多相滤波器IP核的使用,通过仿真,与MATLAB计算的数据相比较,验证了VIVADO中FIR抽取多相滤波器本身是没有考虑滤波器的群延时的,以上的仿真结果很好的说明了如何使用VIIVADO FIR抽取多相滤波器。

相关推荐
机器学习之心9 小时前
Bayes-GRU-Attention的数据多特征分类预测Matlab实现
matlab·分类·gru
叶庭云9 小时前
Matlab 和 R 语言的数组索引都是从 1 开始,并且是左闭右闭的
matlab·编程语言·r·数组索引·从 1 开始
γ..12 小时前
基于MATLAB的图像增强
开发语言·深度学习·神经网络·学习·机器学习·matlab·音视频
IT猿手15 小时前
基于PWLCM混沌映射的麋鹿群优化算法(Elk herd optimizer,EHO)的多无人机协同路径规划,MATLAB代码
算法·elk·机器学习·matlab·无人机·聚类·强化学习
超级大咸鱼1 天前
CW信号的正交解调
matlab·verilog·fpga·数字信号·解调·正交解调·cw
乌恩大侠1 天前
画图,matlab,
开发语言·matlab
吐泡泡科技1 天前
无人机视频传输系统的通信能耗优化
matlab·通信能耗·无人机通信
达不溜方1 天前
基于MATLAB的图像增强
开发语言·人工智能·学习·机器学习·matlab·云服务·效率
信号处理学渣2 天前
matlab的一些时间函数【转】
matlab
十三啊嘞2 天前
Vivado安装System Generator不支持新版Matlab解决方法
fpga·vivado