通用FIR滤波器的verilog实现(内有Lowpass、Hilbert参数生成示例)
众所周知,Matlab 中的 Filter Designer 可以直接生成 FIR 滤波器的 verilog 代码,可以方便地生成指定阶数、指定滤波器参数的高通、低通、带通滤波器,生成的 verilog 代码也可以指定输入输出信号的类型和位宽。然而其生成的代码实在算不上美观,复用性也很差,要实现不同滤波特性的切换就要生成多个滤波器的代码。
出于以上考虑,自己设计实现了 FIR 滤波器的通用 verilog 代码,其滤波器参数通过接口输入,从而可以通过输入不同的参数获得相应的滤波结果。verilog 代码如下:
/* * file : FIR_filter.v* author : 今朝无言* date : 2023-07-03* version : v1.0* description : FIR 滤波器*/
module FIR_filter(
input clk,
input rst_n,input [16*N-1:0] filter_params,input signed [15:0] data_in,
output reg signed [15:0] data_out
);parameter N = 32; //滤波器参数个数
parameter div_N = 16; //sum结果除 2^div_N,作为 filter 的输出//FIR 滤波器参数
reg signed [15:0] b[0:N-1];integer m;
always @(*) beginfor(m=0; m<N; m=m+1) beginb[m] <= filter_params[(m << 4) +: 16];end
endreg signed [15:0] shift_reg[0:N-1];integer i;
always @(posedge clk) beginif(~rst_n) beginfor(i=N-1; i>=0; i=i-1) beginshift_reg[i] <= 16'd0;endendelse beginfor(i=N-1; i>0; i=i-1) beginshift_reg[i] <= shift_reg[i-1];endshift_reg[0] <= data_in;end
endreg signed [31:0] multi[0:N-1];integer j;
always @(*) beginfor(j=0; j<N; j=j+1) beginmulti[j] <= shift_reg[j] * b[j];//这里可以考虑使用multiplier IP核,使用LUT搭建(而这里直接乘使用的是DSP资源,一般的FPGA芯片只有几百个)end
endreg signed [47:0] sum;integer k;
always @(*) beginsum = 0;for(k=0; k<N; k=k+1) beginsum = sum + multi[k];end
endalways @(posedge clk) begindata_out <= sum[47-div_N : 32-div_N];
endendmodule
Lowpass Filter示例
当滤波器阶数较高时,滤波器参数如何给出无疑是个麻烦事,因此又编写了 matlab 代码,可以一键生成所需的 .v 文件以实现参数的配置:
%-----------FIR滤波器参数(生成.v)-----------------
clc,clear,close allfs=1e6;N=20;
Wn=0.1;
b = fir1(N, Wn); % 默认Hamming窗freqz(b,1,512)%% pramas
B=floor(b*65536);
B=B';%% test
t=0:1/fs:1e-3;
s=(mod(t,1e-4)<5e-5)*1.0;%s_filt=filter(B,1,s)/65536;
for i=1:size(s,2)-N-1s_filt(i)=s(i:i+N)*double(B)/65536;
endfigure
subplot(2,1,1)
plot(t,s)
subplot(2,1,2)
plot(t(1:end-N-1),s_filt)%% 生成.v
filename='FIR_params';
fid=fopen(['./v/',filename,'.v'],'w');fprintf(fid,['/* ','\n',...
' * file\t\t\t: ',filename,'.v','\n',...
' * author\t\t: 今朝无言','\n',...
' * date\t\t\t: 2023-07-04','\n',...
' * version\t\t: v1.0','\n',...
' * description\t: FIR 滤波器','\n',...
' */','\n']);fprintf(fid,['module ',filename,'(','\n',...
'output\t[',num2str(size(B,1)*16-1),':0]\tparams\n',...
');\n\n']);for i=1:size(B,1)if(B(i)>=0)hex=dec2hex(B(i),4);elsehex=dec2hex(65536+B(i),4);endfprintf(fid,['assign\t','params[',...num2str(i*16-1),':',num2str((i-1)*16),...']\t= 16','''','h',hex,';\n']);
endfprintf(fid,'\nendmodule\n');fclose(fid);
testbench与测试结果如下
`timescale 1ns/100psmodule FIR_filter_tb();reg clk_100M = 1'b1;
always #5 beginclk_100M <= ~clk_100M;
endlocalparam N = 20; //FIR滤波器阶数wire [16*(N+1)-1:0] filter_params;
FIR_params_0d1 FIR_params_inst(.params (filter_params)
);reg [15:0] data_in;
wire signed [15:0] data_out;FIR_filter #(.N(N+1))
FIR_filter_inst2(.clk (clk_100M),.filter_params (filter_params), //滤波器参数.data_in (data_in),.data_out (data_out)
);reg [7:0] cnt = 8'd0;always @(posedge clk_100M) begincnt <= cnt + 1'b1;if(cnt<100) begindata_in <= -10000;endelse if(cnt<200) begindata_in <= 10000;endelse begindata_in <= 0;end
endinitial begin#10000;$stop;
endendmodule
Hilbert 示例
使用以上 FIR 滤波器代码,还可以实现许多其他滤波功能,比如常用的 90 度相移,可以使用 Hilbert 变换实现,Hilbert 滤波器参数的 matlab 生成代码如下
%-----------------Hilbert----------------------
clc,clear,close all%% Hilbert
N=200;% method 1 这种直接通过 h(n) 表达式生成的更为精确,推荐
n=(1:floor((N-1)/2));
b1=(1-(-1).^n)./(pi.*n);
if mod(N,2)==0b1=[0,b1,0,-b1(end:-1:1)]';
elseb1=[0,b1,-b1(end:-1:1)]';
end% method 2 构造 Hilbert 的频域特性,经 IFFT 获得
H=[-1j*ones(1,floor((N+1)/2)),1j*ones(1,floor(N/2))];
b2=ifft(H);
b2=real(b2)';b=b1;freqz(b,1,100)%% Filter
fs=1e3;
t=0:1/fs:1;
s=5*sin(2*pi*10*t);
% f >= fs/N 时,可以由很好的90度移相s2=filter(b,1,s);figure
hold on
plot(t,s,'r-')
plot(t,s2,'b--')
hold off%% 量化
B=floor(b*32768);
s3=filter(B,1,s)/32768;figure
hold on
plot(t,s,'r-')
plot(t,s3,'b--')
hold off%% 生成params.v
filename='Hilbert_params';
fid=fopen(['./v/',filename,'.v'],'w');fprintf(fid,['/* ','\n',...
' * file\t\t\t: ',filename,'.v','\n',...
' * author\t\t: 今朝无言','\n',...
' * date\t\t\t: 2023-08-04','\n',...
' * version\t\t: v1.0','\n',...
' * description\t: FIR滤波器参数(Hilbert)',...
' N=',num2str(N),'\n',...
' */','\n']);fprintf(fid,['module ',filename,'(','\n',...
'output\t[',num2str(size(B,1)*16-1),':0]\tparams\n',...
');\n\n']);for i=1:size(B,1)if(B(i)>=0)hex=dec2hex(B(i),4);elsehex=dec2hex(65536+B(i),4);endfprintf(fid,['assign\t','params[',...num2str(i*16-1),':',num2str((i-1)*16),...']\t= 16','''','h',hex,';\n']);
endfprintf(fid,'\nendmodule\n');fclose(fid);
仿真结果如下
相关文章:

通用FIR滤波器的verilog实现(内有Lowpass、Hilbert参数生成示例)
众所周知,Matlab 中的 Filter Designer 可以直接生成 FIR 滤波器的 verilog 代码,可以方便地生成指定阶数、指定滤波器参数的高通、低通、带通滤波器,生成的 verilog 代码也可以指定输入输出信号的类型和位宽。然而其生成的代码实在算不上美观…...

有利于提高xenomai /PREEMPT-RT 实时性的一些配置建议
版权声明:转自: https://www.cnblogs.com/wsg1100 一、前言 1. 什么是实时 “实时”一词在许多应用领域中使用,人们它有不同的解释,并不总是正确的。人们常说,如果控制系统能够对外部事件做出快速反应,那么它就是实时运行的。根据这种解释,如果系统速度快,则系统被认…...

【LeetCode】24.两两交换链表中的节点
题目 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入:head [1,2,3,4] 输出:…...

融合大数据、物联网和人工智能的智慧校园云平台源码 智慧学校源码
电子班牌系统用以展示各个班级的考勤信息、授课信息、精品课程、德育宣传、班级荣誉、校园电视台、考场信息、校园通知、班级风采,是智慧校园和智慧教室的对外呈现窗口,也是学校校园文化宣传和各种信息展示的重要载体。将大数据、物联网和人工智能等新兴…...

Spring Boot通过切面实现方法耗时情况
Spring Boot通过切面实现方法耗时情况 依赖 <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version></dependency>自定义注解 package com.geekmice.springbootself…...

深挖 Threads App 帖子布局,我进一步加深了对CSS网格布局的理解
当我遇到一个新产品时,我首先想到的是他们如何实现CSS。当我遇到Meta的Threads时也不例外。我很快就探索了移动应用程序,并注意到我可以在网页上预览公共帖子。 这为我提供了一个深入挖掘的机会。我发现了一些有趣的发现,我将在本文中讨论。 …...
leetcode做题笔记54
给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 思路一:模拟题意 int* spiralOrder(int** matrix, int matrixSize, int* matrixColSize, int* returnSize){int m matrixSize; int n matrixColSi…...

GD32F103VE点灯
GD32F103VE点灯主要用来学习端口引脚的输出配置。它由LED.c,LED.h,SoftDelay.c和main.c组成。 #include "gd32f10x.h" //使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t #include "SoftDelay.h"#include …...

matlab使用教程(8)—绘制三维曲面图
1网格图和曲面图 MATLAB 在 x-y 平面中的网格上方使用点的 z 坐标来定义曲面图,并使用直线连接相邻的点。mesh 和surf 函数以三维形式显示曲面图。 • mesh 生成仅使用颜色来标记连接定义点的线条的线框曲面图。 • surf 使用颜色显示曲面图的连接线和面。 MATL…...
【Nginx14】Nginx学习:HTTP核心模块(十一)其它配置
Nginx学习:HTTP核心模块(十一)其它配置 剩下的一些配置指令没有大的归属,不过也有一些是比较常见的,这部分内容学习完成之后,整个 http 模块相关的核心基础配置指令就全部学习完成了。今晚可以举杯庆祝一下…...

243. 一个简单的整数问题2(树状数组)
输入样例: 10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4输出样例: 4 55 9 15 解析: 一般树状数组都是单点修改、区间查询或者单点查询、区间修改。这道题都是区间操作。 1. 区间修改用数组数组维护差分数组 2. 区间查询&am…...

C#利用自定义特性以及反射,来提大型项目的开发的效率
在大型项目的开发过程中,需要多人协同工作,来加速项目完成进度。 比如一个软件有100个form,分给100个人来写,每个人完成自己的Form.cs的编写之后,要在Mainform调用自己写的Form。 如果按照正常的Form form1 new For…...

【传统视觉】C#创建、封装、调用类库
任务 因为实现代码相对简单,然后又没有使用Opencv,所以就直接用C#实现,C#调用。 1.创建类库 1.1新建一个类库 vs2015 > 文件 > 新建 > 项目 using System; using System.Collections.Generic; using System.Linq;namespace Yo…...

AutoMapper反向映射
#region 用来验证反向映射public class MemberSource{public string Name { get; set; }public MemberInnerSource MemberInnerSource { get; set; }public MemberOtherInnerSource MemberOtherInnerSource { get; set; }}public class MemberInnerSource{public string Name {…...

华为Mate30报名鸿蒙 HarmonyOS 4.0.0.108 系统更新
华为 Mate 30 系列于 2019 年 11 月 1 日上市,包括 Mate 30 4G / 5G、Mate 30 Pro 4G / 5G、保时捷设计版 Mate30 共五款机型。华为 Mate 30 系列 5G 版搭载麒麟 990 5G 处理器,同时支持 SA 及 NSA 5G 双模,适配三大运营商的 5G / 4G / 3G / …...

elementui Cascader 级联选择使用心得
相信大家对于elementui并不陌生,作为适配Vue的优秀UI框架之一,一直被所有的开发者痛并快乐着。今天要记录的就是里边的主角之一Cascader。 首先先介绍一下Cascader ---> 当一个数据集合有清晰的层级结构时,可通过级联选择器逐级查看并选择…...

【ChatGPT 指令大全】怎么利用ChatGPT写报告
目录 选定切入角度 报告开头 大纲生成 草稿撰写 研究报告 提出反对观点 报告总结 研究来源 总结 随着人工智能技术的快速发展,自然语言处理技术在各个领域的应用越来越广泛。其中,ChatGPT作为目前最先进的自然语言处理模型之一,其强…...

【枚举,构造】CF1582 C D
Problem - C - Codeforces 题意: 思路: 思路很简单,只删除一种,直接枚举删除的是哪一种即可 但是回文子序列的判定我vp的时候写的很答辩,也不知道为什么当时要从中间往两边扫,纯纯自找麻烦 然后就越改越…...

POJ 3169 Layout BellmanFord Dijkstra
一、心路历程 这一个题目写了三天,可以说是非常挣扎了,明明是例题,但是就是倔强着不去看书上的题解,WA了7次,TLE了4次。 写了不知道多少条测试用例,一遍一遍的过,一点一点的调试。 最后终于找到…...

数据库管理员知识图谱
初入职场的程序猿,需要为自己做好职业规划,在职场的赛道上,需要保持学习,并不断点亮自己的技能树。 成为一名DBA需要掌握什么技能呢,先让Chat-GPT为我们回答一下: 数据库管理系统 (DBMS)知识ÿ…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...