当前位置: 首页 > news >正文

FPGA教程系列-Vivado中串行FIR设计(非FIR核)

FPGA教程系列-Vivado中串行FIR设计(非FIR核)

什么是FIR滤波器

Finite Impulse Response Filter, 有限冲激响应滤波器,是数字信号处理里最常用、最基础、也最稳定的一类滤波器。“只有零点,没有极点”的滤波器:输出只依赖有限个过去和当前的输入样本,不依赖以前的输出,因此系统总是稳定的。FIR 滤波器是有限长单位冲击响应滤波器。直接型结构如下:

image

FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积,表达式如下:

冲激响应(滤波器系数)

h[n] 是FIR滤波器的冲激响应,即滤波器对单位冲激信号的响应序列。h[n]直接对应系数b_n(如h[0]=b₀, h[1]=b₁, …),用于加权输入信号及其延迟值

通俗理解:h是滤波器的“权重”,决定了滤波器的特性(如低通、高通等)。

延迟算子

z⁻¹ 是Z变换中的延迟算子,表示信号延迟一个采样周期。通俗理解:z⁻¹是“记忆单元”,用于存储输入信号的过去值,供后续加权计算。

Matlab仿真滤波器

FIR滤波器有好几种形式,简单的用matlab程序,仿真出一组系数:

clc;
clear;
close all;% 滤波器参数
order = 10;       % 滤波器阶数 (系数个数 = order + 1)
cutoff = 0.4;     % 截止频率 (归一化)% 1. 使用汉明窗设计
h_hamming = fir1(order, cutoff, 'low', hamming(order+1));% 2. 使用汉宁窗设计
h_hanning = fir1(order, cutoff, 'low', hanning(order+1));% 3. 使用布莱克曼窗设计 (旁瓣衰减更好,但过渡带更宽)
h_blackman = fir1(order, cutoff, 'low', blackman(order+1));% 绘制频率响应进行比较
figure;
freqz(h_hamming, 1, 1024);
hold on;
freqz(h_hanning, 1, 1024);
freqz(h_blackman, 1, 1024);
title('不同窗函数设计的低通滤波器频率响应');
legend('Hamming', 'Hanning', 'Blackman');
grid on;%量化参数
h_x = round(1023*h_hanning) %

image

运行以后可以生成一组参数:

image

这个就是可以在vivado中使用的参数。

Vivado新建工程

有了参数以后,就可以在vivado中建立工程,用单纯的Verilog来编写程序的话,会有很多重复的部分,而System Verilog可以实现参数化的操作,因此这部分选用System Verilog来进行编写。

建立Top文件,fir_top.sv:

`timescale 1ns / 1psmodule fir_top #(// --- 参数定义 ---parameter TAPS = 11,                     // 滤波器阶数parameter DATA_IN_W = 2,                 // 输入数据位宽parameter COEF_W = 14,                   // 系数位宽 (与原IP核匹配)parameter DATA_OUT_W = 20                // 输出数据位宽 (16+ceil(log2(11))=20)
)(input  i_clk,input  i_rst,input  signed [DATA_IN_W-1:0] i_din,output signed [DATA_OUT_W-1:0] o_dout
);// --- 11阶滤波器系数定义 ---// 0, -19, -32, 71, 288, 407, 288, 71, -32, -19, 0localparam signed [COEF_W-1:0] COEF [0:TAPS-1] = '{14'd0,    14'sd19, 14'sd32, 14'd71, 14'd288, 14'd407,14'd288,  14'd71,  14'sd32, 14'sd19, 14'd0};// 注意:Verilog中负数需要用'sd声明,或者在位宽前加s,如14'sd19// --- 延迟链 (移位寄存器) ---reg signed [DATA_IN_W-1:0] x_reg [0:TAPS-1];integer i;always @(posedge i_clk or posedge i_rst) beginif (i_rst) beginfor (i = 0; i < TAPS; i = i + 1) beginx_reg[i] <= {DATA_IN_W{1'b0}};endend else beginx_reg[0] <= i_din;for (i = 1; i < TAPS; i = i + 1) beginx_reg[i] <= x_reg[i-1];endendend// --- 乘法器输出线网数组 ---wire signed [15:0] r [0:TAPS-1]; // 假设乘法器IP核输出为16位// --- 使用 generate 循环实例化乘法器 ---genvar g;generatefor (g = 0; g < TAPS; g = g + 1) begin : mul_genmulter multer_inst (.CLK(i_clk),.A(x_reg[g]),      // 连接到对应的延迟寄存器.B(COEF[g]),       // 连接到对应的系数.SCLR(i_rst),.P(r[g])           // 输出到对应的线网);endendgenerate// --- 求和 ---assign o_dout = r[0] + r[1] + r[2] + r[3] + r[4] + r[5] + r[6] + r[7] + r[8] + r[9] + r[10];endmodule

乘法器采用的是vivado的IP核,可以参考以前的设计,进行设计。注意是带复位信号的乘法器。

top写完以后可以编写testbench文件:

`timescale 1ns / 1psmodule test_fir;
reg i_clk;
reg i_rst;
reg signed[1:0]i_din;
wire signed[15:0]o_dout;fir_tops fir_tops_u(.i_clk              (i_clk),.i_rst              (i_rst),.i_din              (i_din),.o_dout             (o_dout)
);// 时钟生成:周期10ns,频率100MHz
always #5 i_clk = ~i_clk;initial
begin// 初始化i_clk = 1'b1;i_rst = 1'b1;i_din = 2'b00;// 复位持续100ns#100 i_rst = 1'b0;// ==================== 测试序列设计 ====================// 1. 阶跃响应测试 (0 -> +1)$display("=== 阶跃响应测试开始 ===");#50 i_din = 2'b01;  // 输入+1,观察滤波器如何从0上升到稳态值#200;               // 持续200ns,观察完整的上升过程// 2. 负阶跃响应测试 (+1 -> -1)$display("=== 负阶跃响应测试开始 ===");i_din = 2'b11;      // 输入-1,观察滤波器的负向响应#200;               // 持续200ns// 3. 回零测试 (-1 -> 0)$display("=== 回零测试开始 ===");i_din = 2'b00;      // 输入0,观察滤波器回到零点#200;               // 持续200ns// 4. 单脉冲测试 (0 -> +1 -> 0)$display("=== 单脉冲测试开始 ===");i_din = 2'b01;      // 输入单个正脉冲#20;                // 脉冲宽度20nsi_din = 2'b00;      // 回到0#200;               // 观察脉冲响应// 5. 双脉冲测试$display("=== 双脉冲测试开始 ===");i_din = 2'b01;      // 第一个正脉冲#20;i_din = 2'b00;#30;i_din = 2'b01;      // 第二个正脉冲#20;i_din = 2'b00;#200;// 6. 负脉冲测试$display("=== 负脉冲测试开始 ===");i_din = 2'b11;      // 负脉冲#20;i_din = 2'b00;#200;// 7. 交替脉冲序列测试$display("=== 交替脉冲序列测试开始 ===");repeat(5) begini_din = 2'b01;  // 正脉冲#20;i_din = 2'b00;#30;i_din = 2'b11;  // 负脉冲#20;i_din = 2'b00;#30;end// 8. 最后回到零点$display("=== 测试结束,回到零点 ===");i_din = 2'b00;#200;$display("=== 仿真结束 ===");$finish;
end// 监控输出变化
always @(posedge i_clk) begin$display("Time=%0t ns, Input=%d, Output=%d", $time, $signed(i_din), $signed(o_dout));
endendmodule

进行仿真即可,不会仿真的可以问AI

image

可以看到仿真的结果。

工程文件:https://download.csdn.net/download/fantasygwh2015/92261208

http://www.dtcms.com/a/582837.html

相关文章:

  • I2C接口(2):IIC多主设备仲裁机制详解--从原理到Verilog实现
  • 技术网站推广范例怎么建立自己公司的网站
  • 网站的设计公司网咖活动营销方案
  • 北京市朝阳区网站开发公司中国建设监理网站
  • 多语言网站是怎么做的交互设计网站有哪些
  • iis部署网站浏览报404建设网站公司塞尼铁克
  • 使用 PyTorch来构建线性回归的实现
  • 营销型网站设计公司企业网站模板下载服务哪家好
  • 对接物联网使用netty通信与MQTT之间的区别
  • 重塑城市公共安全管理的“智慧之眼”
  • 临海建设局官方网站plc编程入门基础知识
  • 有教做衣服的网站吗免费签名logo设计
  • 2.2.STM32-新建工程
  • 怎么做提卡密网站开发高端市场应该注意
  • 无锡网知名网站教做香肠的网站
  • 做酒招代理的网站江门网红打卡景点蓬江区
  • 双牌网站建设购物网站建设市场调查论文
  • 对象住哪里?——深入剖析 JVM 内存结构与对象分配机制
  • 站长工具高清有吗网推获客平台
  • 网站做流量的论坛贴吧广东广东网站建设工作
  • 中国机械加工网下载番禺seo
  • 如何让美颜SDK更智能?AI赋能下的个性化美颜功能设计详解
  • 软件开发模型——瀑布式模型:软件开发的经典范式及其现代实践
  • 网站集约化建设讲话上海知名的网站建设
  • WordPress建站要花钱七牛图片处理 wordpress
  • 认识linux -- 调试器 - gdb/cgdb的使用
  • 神经流形:大脑功能几何基础的革命性视角
  • 杭州做网站外包公司网站建设实训报告总结
  • 高新区建设局网站网站建设与开发试卷
  • 测试跟踪步骤描述用例交互优化,MeterSphere开源持续测试工具v2.10.26 LTS版本发布