• Xilinx的FIR滤波器IP的设计与仿真


    平台:Vivado2021.1

    芯片:xcku115-flva1517-2-i (active)

    语言:VerilogHDL

    参考文件:pg149.下载地址

    FIR Compiler LogiCORE IP Product Guide • FIR Compiler (PG149) • 阅读器 • AMD 自适应计算文档门户 (xilinx.com)

    FIR滤波器

    最近准备研究以下滤波器。还是从xilinx的官方IP出发,来学习以下这部分。

    使用matlab直观的感受以下。输入信号为5khz,和10mhz正弦波叠加。

    设置FIR滤波器参数。采样率为50mhz,通带起始频率为100KHz,阻带起始频率为1MHz。

    使用matlab打开滤波器设计小工具。产生COE文件。

    直接输入filterDesigner。

    打开后的界面如下图所示。

    我们按照设计参数对滤波器进行设置。

    选择响应类型为低通。选择为FIR滤波器。采样率为50mhz,通带起始频率为100KHz,阻带起始频率为1MHz。设置好后选择设置量化参数。

    滤波器算法选择定点。分子字长选择16位。设置完成后点击应用。

    选择目标。Xilinx系数(.coe)文件。保存在你选定的文件夹中。

    这样就生成了需要的FIR滤波器参数。可以在IP设计阶段直接导入到xilinx的IP中。

    同时还需要将生成的波形数据进行归一化处理。在量化到2^16次方上去。

    所以需要使用matlab产生用于IP核仿真的数据。

    1. %对数据进行归一化
    2. max_abs_value = max(abs(x)); % 获取数据的最大绝对值
    3. normalized_data = x / max_abs_value; % 归一化数据
    4. % 量化为16位数据
    5. simdata = normalized_data;
    6. quantized_data = round(simdata * (2^15 - 1));
    7. % 转换为十六进制数据
    8. hex_data = dec2hex(quantized_data, 4);
    9. %保存数据文件
    10. fileID = fopen('E:\simdata.txt','w');%将数据写入txt。
    11. % fprintf(fileID,'%d\n',quantized_data );%保存为十进制数据
    12. for i = 1:length(hex_data)
    13. fprintf(fileID, '%s\n', hex_data(i, :)); % 将每行的十六进制数据写入文件
    14. end
    15. fclose(fileID);

    这里对产生的波形数据进行过归一化后。转换为16进制数据写入到文件simdata.txt中。

    下面是整体的matlab代码。

    1. fs = 50000000; % 采样率为50MHz
    2. t = 0:1/fs:0.01; % 时间向量,采样时间为0.01秒
    3. f1 = 5000; % 5kHz正弦波频率
    4. f2 = 10000000; % 10mHz正弦波频率
    5. x = sin(2*pi*f1*t) + sin(2*pi*f2*t) ; % 输入信号,多个正弦波叠加
    6. %对数据进行归一化
    7. max_abs_value = max(abs(x)); % 获取数据的最大绝对值
    8. normalized_data = x / max_abs_value; % 归一化数据
    9. % 量化为16位数据
    10. simdata = normalized_data;
    11. quantized_data = round(simdata * (2^15 - 1));
    12. % 转换为十六进制数据
    13. hex_data = dec2hex(quantized_data, 4);
    14. %保存数据文件
    15. fileID = fopen('E:\CODE\Vivado\KU_TEST\ku_test_sim\flash_test\coe\simdata.txt','w');%将数据写入txt。
    16. % fprintf(fileID,'%d\n',quantized_data );%保存为十进制数据
    17. for i = 1:length(hex_data)
    18. fprintf(fileID, '%s\n', hex_data(i, :)); % 将每行的十六进制数据写入文件
    19. end
    20. fclose(fileID);
    21. order = 10; % FIR滤波器阶数
    22. cutoff = [100000]; % 截止频率
    23. b = fir1(order, cutoff/(fs/2)); % 设计FIR低通滤波器系数
    24. y = filter(b, 1, x); % 应用FIR滤波器
    25. % 时域波形绘制
    26. subplot(2, 2, 1);
    27. plot(t, x);
    28. title('滤波前的时域波形');
    29. xlabel('时间');
    30. ylabel('幅值');
    31. subplot(2, 2, 3);
    32. plot(t, y);
    33. title('滤波后的时域波形');
    34. xlabel('时间');
    35. ylabel('幅值');
    36. % 频域波形绘制
    37. X = fft(x);
    38. Y = fft(y);
    39. f = linspace(0, fs, length(t));
    40. subplot(2, 2, 2);
    41. plot(f, abs(X));
    42. title('滤波前的频域波形');
    43. xlabel('频率');
    44. ylabel('幅值');
    45. subplot(2, 2, 4);
    46. plot(f, abs(Y));
    47. title('滤波后的频域波形');
    48. xlabel('频率');
    49. ylabel('幅值');

    使用matlab产生两个波形叠加。通过FIR滤波器后,画出了滤波前后的时域频域波形。

    下面是FPGA部分。

    IP核的资料是PG149,里面详细的介绍了这个IP资源。这里我们从应用的角度出发来使用这个IP。

    接口方面。还是使用了熟悉的AXI接口。

    接口非常的简单。只需要输入valid核数据即可。输出端有valid和数据有效。

    此IP核的主界面。

    在左侧部分分别是,IP核的接口。频率响应曲线。以及详细信息。和系数重载功能。

    选择系数源,分别为coefile(COE文件)和Vector(系数矢量)。

    这里我们选择coe文件,我们直接从matlab中生成的coe文件。直接选定到文件夹。

    Number of Coefficient Sets多个系数集,对于多系数过滤器,单个.coe文件用于指定系数集。 每个系数集应附加到前一组系数。我们这里没有使用。

    Number of Coefficients (per set)系数数量(每组):每个滤波器组的滤波器系数数量。自动计算。

    Use Reloadable Coefficients使用可重新加载的系数:当选择重新加载选项时,在核心上提供一个系数重新加载接口。这里我们不使用。

    Filter Type滤波器类型:支持五种滤波器类型:单速率FIR(有限脉冲响应滤波器)、插值FIR、抽取FIR、Hilbert变换和插值FIR

    我们选择为单速率。

    下面的速率变化类型和插值速率抽值速率。分别对应于不同类型的滤波器设置。

    下面是通道规范页。

    Channel Sequence支持基本的和高级的。我们选择基本的即可。

    Number of Channels通道数我们选择一通道。

    下面的Select Sequence和Sequence ID List在高级模式中使用。

    Select format选择格式。

    Sample Period采样周期。

    Input Sampling Frequency采样频率。跟你设置的采样频率一致。

    Clock Frequency时钟频率。

    Coefficient Type系数数据可以指定为有符号或无符号。

    Quantization量化方式指定为整数。

    Coefficient Width系数位宽,这里选择为16位模式。选择后在matlab中生成coe文件时选择一致。

    Coefficient Structure系数结构:支持五种系数结构:非对称、对称、负对称、半带和希尔伯特。

    数据路径选择。

    同样的,选择输入数类型,数据位宽。这里选择后需要在模拟产生输入数据时,产生一致。

    Output Rounding Mode输出数据的精度。默认为全精度。后面的选择可以选择输出数据位宽。

    详细页

    Goal优化选项。使用最下面积最快速度和custom定制。

    Select Optimization和List选择分别定制优化。

    下面的Memory Options就是选择缓存的类型。这里可以根据你的需求自己选择或者自动。

    DSP Slice Column Options:DSP选择。

    Multi-column Support可以选择为自动和定制。

    Interface Tab接口页。

    Data Channel Options选择AXI接口相关的参数。

    TLAST指示AXI需要支持TLAST位不。以及是否使用tuser,tready等。

    Configuration Channel Options

    CONFIG通道用于选择活动的滤波器系数集。该通道还用于应用重新加载的滤波器系数。

    Reload Channel Options和重加载相关。

    Control Signals控制信号。选择复位时钟等等。

    总结界面。

    我们在顶层例化该IP核。

    下面我们对该IP核进行仿真。

    下面分别是例化代码和仿真tb。

    1. // *********************************************************************************/
    2. // Project Name :
    3. // Author : i_huyi
    4. // Email : i_huyi@qq.com
    5. // Creat Time : 2023/10/20 16:46:10
    6. // File Name : .v
    7. // Module Name :
    8. // Called By :
    9. // Abstract :
    10. //
    11. // CopyRight(c) 2020, xxx xxx xxx Co., Ltd..
    12. // All Rights Reserved
    13. //
    14. // *********************************************************************************/
    15. // Modification History:
    16. // 1. initial
    17. // *********************************************************************************/
    18. // *************************
    19. // MODULE DEFINITION
    20. // *************************
    21. `timescale 1 ns / 1 ps
    22. module fir#(
    23. parameter U_DLY = 1
    24. )
    25. (
    26. //
    27. input wire[15:0] fir_data_in ,
    28. input wire fir_data_inen ,
    29. output wire[39:0] fir_data_out ,
    30. output wire fir_data_outvalid ,
    31. //
    32. input wire clk ,
    33. input wire rst_n
    34. );
    35. //--------------------------------------
    36. // localparam
    37. //--------------------------------------
    38. //--------------------------------------
    39. // register
    40. //--------------------------------------
    41. //--------------------------------------
    42. // wire
    43. //--------------------------------------
    44. wire s_axis_data_tvalid ;
    45. wire[15:0] s_axis_data_tdata ;
    46. wire s_axis_data_tready ;
    47. wire m_axis_data_tvalid ;
    48. wire[39:0] m_axis_data_tdata ;
    49. //--------------------------------------
    50. // assign
    51. //--------------------------------------
    52. assign s_axis_data_tvalid = fir_data_inen;
    53. assign s_axis_data_tdata = fir_data_in;
    54. assign fir_data_out = m_axis_data_tdata;
    55. assign fir_data_outvalid = m_axis_data_tvalid;
    56. //------------------------------------------------------------
    57. //------------------------------------------------------------
    58. fir_compiler_0 u_fir_compiler_0 (
    59. .aresetn (rst_n ),// input wire aresetn
    60. .aclk (clk ),// input wire aclk
    61. .s_axis_data_tvalid (s_axis_data_tvalid ),// input wire s_axis_data_tvalid
    62. .s_axis_data_tready (s_axis_data_tready ),// output wire s_axis_data_tready
    63. .s_axis_data_tdata (s_axis_data_tdata ),// input wire [15 : 0] s_axis_data_tdata
    64. .m_axis_data_tvalid (m_axis_data_tvalid ),// output wire m_axis_data_tvalid
    65. .m_axis_data_tdata (m_axis_data_tdata )// output wire [39 : 0] m_axis_data_tdata
    66. );
    67. //------------------------------------------------------------
    68. //------------------------------------------------------------
    69. //------------------------------------------------------------
    70. //------------------------------------------------------------
    71. endmodule

    仿真tb

    1. `timescale 1ns / 1ps
    2. //
    3. // Company:
    4. // Engineer:
    5. //
    6. // Create Date: 2023/10/23 09:33:40
    7. // Design Name:
    8. // Module Name: fir_tb
    9. // Project Name:
    10. // Target Devices:
    11. // Tool Versions:
    12. // Description:
    13. //
    14. // Dependencies:
    15. //
    16. // Revision:
    17. // Revision 0.01 - File Created
    18. // Additional Comments:
    19. //
    20. //
    21. module fir_tb;
    22. //input
    23. reg [15:0] fir_data_in;
    24. reg fir_data_inen;
    25. reg clk;
    26. reg rst_n;
    27. reg [15:0] simdata [0:32767];
    28. reg [15:0] read_data;
    29. //output
    30. wire[39:0] fir_data_out;
    31. wire fir_data_outvalid;
    32. fir u_fir(
    33. .fir_data_in (fir_data_in ),
    34. .fir_data_inen (fir_data_inen ),
    35. .fir_data_out (fir_data_out ),
    36. .fir_data_outvalid (fir_data_outvalid ),
    37. //
    38. .clk (clk ),
    39. .rst_n (rst_n )
    40. );
    41. //------------------------------------------------------
    42. //复位参数
    43. //------------------------------------------------------
    44. integer i;
    45. //设置复位参数
    46. initial
    47. begin
    48. $display("[%t] : reset begin...", $realtime);
    49. rst_n = 0;
    50. for( i=0 ; i<100 ; i=i+1)
    51. begin
    52. @(posedge clk );
    53. end
    54. $display("[%t] : reset stop...", $realtime);
    55. rst_n = 1;
    56. end
    57. initial
    58. begin
    59. clk = 0;
    60. read_data = 0;
    61. fir_data_in = 0;
    62. fir_data_inen = 0;
    63. wait(rst_n == 1);
    64. fir_data_inen = 1;
    65. $display("[%t] : read data begin...", $realtime);
    66. repeat(32767)
    67. begin
    68. @(posedge clk);
    69. read_data = read_data + 16'd1;
    70. fir_data_in = simdata[read_data];
    71. end
    72. repeat(100)@(posedge clk);
    73. $display("[%t] : read data stop...", $realtime);
    74. $finish(0);
    75. end
    76. initial
    77. begin
    78. $readmemh("E:/CODE/Vivado/KU_TEST/ku_test_sim/flash_test/coe/simdata.txt",simdata);
    79. end
    80. always #2 clk = ~clk;
    81. endmodule

    在经过一段时间的仿真后,我们看到通过模拟产生的正弦波数据的高频分量在FIR滤波器的作用下只保留了低频部分。

    今天的FIR滤波器就学习到这里。

  • 相关阅读:
    原生js实现扫雷
    React 学习笔记:JSX 语法
    vim 不常见但好用的命令
    navicat远程连接数据库遇到的问题 10060 unknown error
    蓝桥杯打卡Day8
    【博客440】Linux netlink:用户态进程与内核态进程通信
    Java对List的操作
    有更新:2023华为HCIA+HCIP最全Datacom题库解析(附全套文档赠送)
    Scala学习笔记16: 注解
    uniapp封装http请求
  • 原文地址:https://blog.csdn.net/hy_520520/article/details/134001178