通用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)知识ÿ…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
