matlab与FPGA无线通信、FPGA数字信号处理系列(6)—— 在 Vivado 中 使用 Verilog 实现并行 FIR 滤波器-1

     在 FPGA 实现 FIR 滤波器时,最常用的是直接型结构,简单方便,在实现直接型结构时,可以选择串行结构/并行结构/分布式结构。
     并行结构即并行实现 FIR 滤波器的乘累加操作,数据的处理速度较快,使用多个乘法器同时计算乘法操作,数据输入速率可以达到系统处理时钟的速率,且与阶数无关;
     上一讲(5) Verilog 实现串行滤波器

     (3)Matlab 与 Vivado 联合仿真 FIR 滤波器

MATLAB 与 FPGA无线通信、图像处理、数字信号处理系列 汇总

在这里插入图片描述

1. 新建工程和文件

(1)新建 Verilog 文件
    输入信号 16-bit,输出信号 16-bit,复位 rst_n 低电平进行复位;
在这里插入图片描述
(2)获取滤波器系数 h0 ~ h7;
     按照 第一讲 通过matlab的fdatool工具箱设计FIR滤波器 的方式使用 matlab 设计 FIR 低通滤波器,设置为系数 8-bit 量化,采样时钟 32 MHz(并行处理时输入输入速率可以达到系统时钟速率),截止频率设为 1 .5 MHz,与前面调用 IP 核的时候一致(32 MHz时钟,0.5MHz信号 + 5 MHz 高频噪声,99阶);
     观察右上方的幅频特性曲线,发现 7 阶的滤波器效果确实不好,在 5 MHz处幅度衰减较小,所以此处更改噪声为 13 MHz,该频率点的衰减较大,滤波效果明显;
在这里插入图片描述
     量化后导出参数,可以直接用 .coe 文件导出备用,导出后 matlab 也会自动打开系数文件,用 Verilog 语言的常数定义参数 h0 ~ h7(注意指定为有符号数);
在这里插入图片描述
(3)加权求和进行滤波
     FIR 滤波器的输出是输入信号不同延时阶段的数据和滤波器系数的卷积(乘累加操作,先做多组乘法,再把乘法的积累加起来),也相当于每个输入延时数据有不同的权值,进行加权和;
在这里插入图片描述
    按照上面的结构框图,先做 8 次乘法,再把乘法的积相加;
在这里插入图片描述

2. 使用 matlab 产生仿真信号

参数:抽样频率 Fs = 32 MHz,信号 f1 = 0.5 MHz,信号 f2 = 13 MHz,具体参见 第三讲 Matlab 与 Vivado 联合仿真 FIR 滤波器
在这里插入图片描述

3. 编写仿真文件testbench

(1)例化模块;
(2)写 initial 块,初始化时钟、复位等;
(3)写 always 块,给出时钟翻转等;
(4)读写 .txt 文件,将 matlab 写好的 .txt 的数据赋给输入,把输出数据写入 .txt 文件给 matlab 分析;
     具体见 第三讲 Matlab 与 Vivado 联合仿真 FIR 滤波器
在这里插入图片描述

4. 仿真

(1)Verilog 仿真
     可以看到,高频噪声基本被滤除,但是肉眼能观察出波形与标准正弦波有一定差距;
在这里插入图片描述
(2)Matlab仿真
     Matlab仿真,分别是 f1、f2、f1+f2、滤波后的数据;
在这里插入图片描述
     使用 matlab 做 FFT 进行频谱分析,使用 7 阶(8个系数)FIR 滤波器能够很好的保留低频 0.5 MHz 信号,滤除高频 13 MHz 信号;
在这里插入图片描述
(3)综合的 RTL 图
     综合后共用到 6 个乘法器和 7 个加法器, Verilog 共计有 8 次乘法,但是其中有 2 个乘法的乘数是常数 0,所以 Vivado 只综合出 6 个乘法器;
在这里插入图片描述
     与串行的对比,下图为串行 FIR 滤波器的 RTL 图:
在这里插入图片描述

5. 截位输出部分更改

     还是看这张图,在对输入的 16-bit 数据做运算后,为了保证数据不溢出,得到的结果位宽逐渐变大,但是最后输出又是 16-bit,此时需要对数据进行截位(如果不截位,那么当一个数字信号处理系统较复杂的时候,数据的位宽会非常大,在处理中时不现实的),
     当对本例中的 32-bit 的数据进行截位时,从哪里开始截取是一个经常会遇到的问题:
(1)截取高 16-bit (data_out_temp[31:16]),当数据比较大的时候可以这样做(高位上都是有效数据,用十进制举例 9*9 = 81,取十进制高位近似为 80,类比到二进制),这样相当于损失了一些低位的精度;
(2)截取低 16-bit (data_out_temp[15:0]) ,当数据比较小的时候可以(高位上没有有效数据,用十进制举例 2 * 2 = 4,取十进制低位为 4);
(3)根据仿真出来的数据的表示范围,去掉高位的符号位,截取实际需要的数据;
在这里插入图片描述
     需要对 data_out_temp[31:0] 截位(先截高 16 位作为 data_out 看波形),所以在仿真中先把该信号添加到波形显示窗口,该信号是一个内部信号,没有在输出端口,按照下图找到 testbench 仿真例化的器件,找到下方的 data_out_temp 信号并右键 Add to Wave Window(箭头1),点击 Restart(箭头2)之后再仿真 Run(箭头3),调成模拟波形 Analog(具体参见 Matlab 与 Vivado 联合仿真 FIR 滤波器);
在这里插入图片描述
     按照下图箭头所示展开信号,可以看到 data_out_temp 信号的 23 ~ 31 bit 都是一样的,代表符号位,0 代表正数,1 代表负数,实际上只需要 1 位符号位代表正负即可,可以取 data_out_temp[23:8] 这 16 位;
在这里插入图片描述
     选中 data_out_temp[23:8] 这 16 位后 右键 新建虚拟总线(New Virtual Bus),类似的,把 data_out_temp[22:7] 也新建成虚拟总线(New Virtual Bus 1);
在这里插入图片描述
     可以看到,data_out_temp[23:8] 的波形并没有受到影响,data_out_temp[23:8] 的波形已经不能体现 data_out_temp 的特性,所以可以截取 data_out_temp[23:8] 作为 data_out;

assign data_out = data_out_temp[23:8];

在这里插入图片描述
    如下图,使用 data_out_temp[23:8] 作为 data_out 后,在黄线时刻滤波输出值为 16619,和输入信号 data_in 在一个数量级,且小于 data_in,这是因为滤除了上面的高频噪声,这样的结果符合实际情况;
在这里插入图片描述
此处波形如果不对的原因还可能涉及到对有符号数的处理问题
Verilog学习笔记——有符号数的乘法和加法

MATLAB 与 FPGA无线通信、图像处理、数字信号处理系列 汇总

发布了30 篇原创文章 · 获赞 56 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/DengFengLai123/article/details/104065126