前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >matlab与FPGA数字滤波器设计(6)—— Vivado 中使用 Verilog 实现并行 FIR 滤波器/截位操作

matlab与FPGA数字滤波器设计(6)—— Vivado 中使用 Verilog 实现并行 FIR 滤波器/截位操作

作者头像
FPGA探索者
发布2021-03-15 10:38:12
4.2K0
发布2021-03-15 10:38:12
举报
文章被收录于专栏:FPGA探索者

在 FPGA 实现 FIR 滤波器时,最常用的是直接型结构,简单方便,在实现直接型结构时,可以选择串行结构/并行结构/分布式结构。

并行结构即并行实现 FIR 滤波器的乘累加操作,数据的处理速度较快,使用多个乘法器同时计算乘法操作数据输入速率可以达到系统处理时钟的速率,且与阶数无关(相比较串行,用了更多的资源,但提高了处理速度,典型的“以资源换速度”的设计思想)

1. 新建工程和文件

(1) 新建 Verilog 文件

输入信号 16-bit输出信号 16-bit,复位 rst_n 低电平进行复位;

(2) 获取滤波器系数 h0 ~ h7;

按照 第一讲的方式使用 matlab 的 fdatool 工具箱设计 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,具体参见第三讲

3. 编写仿真文件testbench

(1)例化模块;

(2)写 initial 块,初始化时钟、复位等;

(3)写 always 块,给出时钟翻转等;

(4)读写 .txt 文件,将 matlab 写好的 .txt 的数据赋给输入,把输出数据写入 .txt 文件给 matlab 分析;

具体见第三讲

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与FPGA数字滤波器设计(3)—— 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,这是因为滤除了上面的高频噪声,这样的结果符合实际情况

matlab与FPGA数字滤波器设计(5)—— Verilog 串行 FIR 滤波器

matlab与FPGA数字滤波器设计(4)—— Vivado DDS 与 FIR IP核设计 FIR 数字滤波器系统

matlab与FPGA数字滤波器设计(3)—— Matlab 与 Vivado 联合仿真 FIR 滤波器

matlab与FPGA数字滤波器设计(2)——Vivado调用IP核设计FIR滤波器

matlab与FPGA数字滤波器设计(1)——通过matlab的fdatool工具箱设计FIR数字滤波器

Verilog学习笔记——有符号数的乘法和加法

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FPGA探索者 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档