碎碎思 · 2月19日

FPGA DSP:Vivado 中带有 DDS 的 FIR 滤波器

本文使用 DDS 生成三个信号,并在 Vivado 中实现低通滤波器。低通滤波器将滤除相关信号。

image.png

介绍

用 DDS 生成三个信号,并在 Vivado 中实现低通滤波器。低通滤波器将滤除较快的信号。

本文分为几个主要部分:

  • 信号生成:展示如何使用 DDS(直接数字合成)IP 生成测试信号 - 10 MHz 信号和 500 kHz 信号,然后将它们组合起来创建混合信号进行测试。
  • FIR 滤波器设计:解释影响 FIR 滤波器性能的关键因素,包括:
  • 抽头数量及其对滤波器响应的影响
  • 量化和系数位宽设计
  • 权衡资源利用
  • 设计:演示使用 Vivado 进行设计,包括

设置 FIR IP

使用 MATLAB 生成的系数配置滤波器参数

设置适当的位宽和时钟频率

添加必要的组件,如时钟源和 ILA(集成逻辑分析仪)

  • 测试和验证:显示如何通过以下方式验证滤波器的操作:

仿真结果显示高频分量的滤波

FPGA 板上的硬件实现

使用基于计数器的脉冲发生器观察滤波器脉冲响应的特殊技术

第 1 部分:DDS 设置,用于生成两个信号和混合信号

首先为测试台生成信号:

Image

在 BD 设计中添加 DDS IP。在配置选项卡中,将系统时钟设置为 100 MHz。

Image

由于我们只需要生成正弦波,因此在 Implementation 选项卡中,选择输出为 Sine 选项,并取消选择相位输出选项。在 Output Frequency 选项卡中,将 Channel 1 的频率设置为 500 kHz。

Image

Image

在 BD 设计中添加另一个 DDS IP。重复相同的设置,但这次将输出频率设置为 10 MHz。

Image

在 BD 设计中添加一个加法器。将其输入位宽设置为 8,将其输出位宽设置为 9。

Image

将两个 DDS 编译器的输出连接到加法器的输入。这将生成混合信号。

在设计中添加一个模拟时钟发生器,并将其频率设置为 100MHz。该频率也是设计的采样率

DDS 编译器仿真结果:

如仿真结果所示:

Image

第一个正弦波的周期为 2000 ns,这是一个 500 kHz 的信号。

第二个正弦波的周期为 100 ns,这是一个 10 MHz 信号。

还可以观察混合信号,其中较快信号的幅度以较慢信号的频率波动,从而显示了两个频率的组合。

Vivado FIR 滤波器仿真

Image

FIR 滤波器配置:FIR 滤波器的性能受几个因素影响:

  • 抽头数量:

增加抽头数量可改善滤波器响应,从而使通带更平坦,波纹更少,振铃减少。

更多的抽头数还会增强截止频率的衰减,从而提高滤波器的精度。 然而,更多的抽头会引入更大的延迟,这可能不适合某些 DSP 系统。

Image

不同抽头数的 FIR 滤波器响应比较

  • 量化和滤波器系数位宽:

量化-通过将数字映射到由分配的位宽决定的一组固定的离散值来降低数字的精度。

使用较少的位数进行量化会降低滤波器系数的准确性,从而对滤波器的性能产生负面影响。

  • 资源权衡:

滤波器性能和 FPGA 资源利用率之间存在权衡。

增加抽头数量或系数的位宽需要更多的 DSP 资源,这可能会消耗 FPGA 很多资源。

Image

两种不同 FIR 滤波器所需的 FPGA 资源

通过平衡这些因素,可以优化 FIR 滤波器以满足应用程序的特定要求。

在 Matlab 中生成量化 FIR 滤波器抽头

为了简化工作,提供了一个可以轻松生成量化 FIR 滤波器的 Matalab 代码,可以在 Vivado 中直接使用它:

close all  
clear all  
clc  
%% setup the parameters here  
Sample_Rate = 50e6;  
cutoff_frequency = 5e6;  
number_of_filter_taps = 191;% must be odd number!  
filter_taps_bitwidth = 10;  
lowpass_highpass = 'low'; % should be low or high  
%% Caluculate the taps  
Nyquist_frequency =Sample_Rate/2 ;  
Wn = cutoff_frequency/(Nyquist_frequency);  
%Generate a row vector b containing the n+1 coefficients   
filter_taps = fir1(number_of_filter_taps-1,Wn,lowpass_highpass);  
%% Quantization   
% one bit for sign  
filter_taps=floor(filter_taps/max(filter_taps)*(2^(filter_taps_bitwidth-1)-1));  
%% plot the filter response  
N = 1024; % Number of points for the frequency response  
[H, f] = freqz(filter_taps, 1, N, Sample_Rate); % Calculate the frequency response  
% Magnitude and phase response  
magnitude = abs(H); % Magnitude response

% Plot the filter response  
% Magnitude response plot  
figure;  
plot(f, 20*log10(magnitude),'linewidth',1.3); % Plot magnitude in dB  
grid on;  
title('Magnitude Response (dB)',FontSize=22);  
xlabel_txt = 'Frequency (Hz)';  
xlabel(xlabel_txt,FontSize=22);  
ylabel('Magnitude (dB)',FontSize=22);  
%xlim([0 30e6])  
figure  
 freqz(filter_taps,1)  
figure  
stem(filter_taps,'linewidth', 1.3)  
grid on;  

在提供的 Matlab 代码中,需要配置以下参数:

  • 采样率: 这是采样频率,在我们的设计中它对应于驱动系统的时钟频率。
  • 截止频率: 指定滤波器的截止频率。
  • 抽头数: 设置滤波器的抽头数,决定滤波器的精度和性能。
  • 抽头位宽: 定义滤波器系数的位宽,影响量化精度。
  • 滤波器类型: 选择需要的滤波器类型。此代码目前仅支持高通和低通滤波器。

Vivado 中的 FIR 编译器 IP 设置:

借助 Matlab 代码,生成截止频率为 1MHz、量化为 16 位的 21 个滤波器抽头。需要进行少许修改才能使生成的值在 Vivado 中可用。

复制 FIR 滤波器抽头并将其粘贴到“滤波器选项”选项卡 下的“系数向量”字段中。

Image

请注意,一旦更新滤波器系数,实施选项卡中的输出宽度将自动调整。

在“通道规范”选项卡中,设置采样率和时钟频率匹配连接到 FIR 滤波器的时钟。在本教程中,我们使用 100 MHz 时钟。

Image

在“实施”选项卡中,配置“输入位宽”以匹配输入信号的位宽。例如,由于此设计中加法器的输出有 9 位,因此将输入位宽设置为 9。

Image

这样 FIR 滤波器现已配置完毕并可以使用。

请注意,FIR 滤波器的输入和输出位宽与正确的字节数对齐。例如,当我们将输入位宽设置为 9 位时,滤波器的实际输入位宽会调整为 2 个字节(16 位)。

仿真结果

仿真就会观察到 FIR 滤波器表现为低通滤波器,衰减频率更高的信号。

Image

Vivado 综合

上诉设计都是可综合的,在系统内为设计添加时钟后就可以进行综合和实现了。

最后,需要在设计中加入一个 ILA 来监控和研究目标信号。移除所有额外的端口,并将它们连接到 ILA。

Image

使用上面的架构需要使用 SDK 或者 Vitis 运行一个简单的“HelloWorld!”程序。

如果使用板载时钟就按照需求进行修改。

Image

运行后,应该能看到与仿真相同的结果:

Image

END

作者:碎碎思
原文:OpenFPGA

相关文章推荐

更多 FPGA 干货请关注FPGA的逻辑技术专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
10631
内容数
601
FPGA Logic 二三事
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息