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

embedded/2024/10/8 12:01:53/

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

目录

前言

一、滤波器系数生成

MATLAB%E7%94%9F%E6%88%90%E4%BB%BF%E7%9C%9F%E6%95%B0%E6%8D%AE-toc" style="margin-left:0px;">二、用MATLAB生成仿真数据

VIVADO%20FIR%E6%8F%92%E5%80%BC%E5%A4%9A%E7%9B%B8%E6%BB%A4%E6%B3%A2%E5%99%A8%E4%BD%BF%E7%94%A8-toc" style="margin-left:0px;">三、VIVADO FIR抽取多相滤波器使用

VIVADO%20FIR%E6%BB%A4%E6%B3%A2%E5%99%A8%E4%BB%BF%E7%9C%9F-toc" style="margin-left:0px;">四、VIVADO FIR抽取多相滤波器仿真

VIVADO%E5%B7%A5%E7%A8%8B%E4%B8%8B%E8%BD%BD-toc" style="margin-left:0px;">五、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%E7%94%9F%E6%88%90%E4%BB%BF%E7%9C%9F%E6%95%B0%E6%8D%AE">二、用MATLAB生成仿真数据

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

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]);
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 FrequencyFpass = 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%20FIR%E6%8F%92%E5%80%BC%E5%A4%9A%E7%9B%B8%E6%BB%A4%E6%B3%A2%E5%99%A8%E4%BD%BF%E7%94%A8">三、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%20FIR%E6%BB%A4%E6%B3%A2%E5%99%A8%E4%BB%BF%E7%9C%9F" style="background-color:transparent;">四、VIVADO FIR抽取多相滤波器仿真

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

`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
beginforever #(PERIOD/2)  clk=~clk;
endreg 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) beginif(i<1024) begins_axis_data_tvalid<=1;s_axis_data_tdata <= signal[i];i <= i + 1;endelsebegins_axis_data_tvalid<=0;s_axis_data_tdata <=0;endendend 
endinteger dout_file;
initial 
begindout_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
endinitial
beginforeverbegin@(posedge clk) beginif(m_axis_data_tvalid)$fdisplay(dout_file,"%d",$signed(m_axis_data_tdata)); //保存有符号数据endend
endFIR_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%E5%B7%A5%E7%A8%8B%E4%B8%8B%E8%BD%BD">五、VIVADO工程下载

https://download.csdn.net/download/m0_66360845/89797080icon-default.png?t=O83Ahttps://download.csdn.net/download/m0_66360845/89797080


总结

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


http://www.ppmy.cn/embedded/120826.html

相关文章

《厦门大学学报(自然科学版)》

《厦门大学学报&#xff08;自然科学版&#xff09;》以促进科学技术发展为宗旨&#xff0c;为科技工作者提供一个高水平的学术交流与传播平台。主要刊登在基础科学、技术科学和应用科学领域有影响的科技论文。栏目包括“厦门大学研究亮点”“南强青年学者”“研究论文”“研究…

软件都用哪些编程语言写的?

一句话总结编程语言 编程语言千千万&#xff0c;每种语言都有自身独特的魅力。 一句话总结 C语言简洁自然、灵活又可怕。 C是C的超集&#xff0c;类型严格&#xff0c;泛型模板强大至极&#xff0c;博大精深很难摸透。 Java是更安全的C&#xff0c;跨平台中间件的老大哥。 C#为…

【含文档】基于Springboot+Vue的果蔬种植销售一体化服务平台(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定…

设计模式-策略模式-200

优点&#xff1a;用来消除 if-else、switch 等多重判断的代码&#xff0c;消除 if-else、switch 多重判断 可以有效应对代码的复杂性。 缺点&#xff1a;会增加类的数量&#xff0c;有的时候没必要为了消除几个if-else而增加很多类&#xff0c;尤其是那些类型又长又臭的 原始代…

Arch Linux 与 Valve 建立直接合作关系

Arch Linux 项目负责人 Levente Polyak 在邮件列表上宣布与 Valve 建立直接合作关系。 Valve 将在两个方面支持 Arch Linux 项目&#xff1a;构建服务基础设施和安全签名 Enclave。 这一消息并不令人惊讶或出人意料&#xff0c;因为Steam Deck 掌机使用的发行版 SteamOS 其实…

linux下recoketmq安装教程

RocketMQ 是一个开源的分布式消息中间件&#xff0c;由阿里巴巴团队开发并捐赠给 Apache 基金会。它提供了高吞吐量、高可用性和易扩展性等特性。下面是在 Linux 系统上安装 RocketMQ 的基本步骤。 环境要求 64位操作系统&#xff1a;推荐使用Linux/Unix/Mac&#xff0c;但也…

【若依】postman调试出现认证失败,无法访问系统资源

如果前后端都已经连接通了&#xff0c;但是调试出现错误代码&#xff0c;可能是因为没有授权的问题&#xff0c;需要获得授权。 授权内容在cookie中 把cookie中的token内容粘贴到postman里面 这个时候再在postman里测试接口&#xff0c;发现可以拿到数据了

打造备份一体机,群晖科技平台化战略再进阶

数字经济时代&#xff0c;海量数据不断涌现&#xff0c;并成为核心生产要素&#xff0c;驱动着企业生产方式和商业模式发生深刻变革。 与其他生产要素不同&#xff0c;数据要素具有非稀缺性、非竞争性等特征&#xff0c;且只有在具体业务场景中才能充分释放其价值。尤其是近年…