通用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 @(*) begin
	for(m=0; m<N; m=m+1) begin
		b[m]	<= filter_params[(m << 4) +: 16];
	end
end

reg	signed	[15:0]	shift_reg[0:N-1];

integer	i;
always @(posedge clk) begin
	if(~rst_n) begin
		for(i=N-1; i>=0; i=i-1) begin
			shift_reg[i]	<= 16'd0;
		end
	end
	else begin
		for(i=N-1; i>0; i=i-1) begin
			shift_reg[i]	<= shift_reg[i-1];
		end
		shift_reg[0]		<= data_in;
	end
end

reg		signed	[31:0]	multi[0:N-1];

integer	j;
always @(*) begin
	for(j=0; j<N; j=j+1) begin
		multi[j]	<= shift_reg[j] * b[j];
		//这里可以考虑使用multiplier IP核,使用LUT搭建(而这里直接乘使用的是DSP资源,一般的FPGA芯片只有几百个)
	end
end

reg		signed	[47:0]	sum;

integer	k;
always @(*) begin
	sum		= 0;
	for(k=0; k<N; k=k+1) begin
		sum	= sum + multi[k];
	end
end

always @(posedge clk) begin
	data_out	<= sum[47-div_N : 32-div_N];
end

endmodule

Lowpass Filter示例

  当滤波器阶数较高时,滤波器参数如何给出无疑是个麻烦事,因此又编写了 matlab 代码,可以一键生成所需的 .v 文件以实现参数的配置:

%-----------FIR滤波器参数(生成.v)-----------------
clc,clear,close all

fs=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-1
    s_filt(i)=s(i:i+N)*double(B)/65536;
end

figure
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);
    else
        hex=dec2hex(65536+B(i),4);
    end
    fprintf(fid,['assign\t','params[',...
        num2str(i*16-1),':',num2str((i-1)*16),...
        ']\t= 16','''','h',hex,';\n']);
end

fprintf(fid,'\nendmodule\n');

fclose(fid);

  testbench与测试结果如下

`timescale 1ns/100ps

module FIR_filter_tb();

reg		clk_100M	= 1'b1;
always #5 begin
	clk_100M	<= ~clk_100M;
end

localparam	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) begin
	cnt		<= cnt + 1'b1;

	if(cnt<100)	begin
		data_in		<= -10000;
	end
	else if(cnt<200)	begin
		data_in		<= 10000;
	end
	else begin
		data_in		<= 0;
	end
end

initial begin
	#10000;
	$stop;
end

endmodule

在这里插入图片描述

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)==0
    b1=[0,b1,0,-b1(end:-1:1)]';
else
    b1=[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);
    else
        hex=dec2hex(65536+B(i),4);
    end
    fprintf(fid,['assign\t','params[',...
        num2str(i*16-1),':',num2str((i-1)*16),...
        ']\t= 16','''','h',hex,';\n']);
end

fprintf(fid,'\nendmodule\n');

fclose(fid);

  仿真结果如下

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/67145.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智能型静电消除器的优势有哪些?

智能型静电消除器是一种使用先进技术和智能控制系统来消除静电问题的设备。静电是由于电荷不平衡而引起的现象&#xff0c;常见于工业生产、医疗设备、办公环境等场合。静电的存在可能导致电子设备故障、火灾、等问题。 智能型静电消除器与传统静电消除器相比&#xff0c;具有以…

Python做一个绘图系统3:从文本文件导入数据并绘图

文章目录 导入数据文件对话框修改绘图逻辑源代码 Python绘图系统系列&#xff1a;将matplotlib嵌入到tkinter 简单的绘图系统 导入数据 单纯从作图的角度来说&#xff0c;更多情况是已经有了一组数据&#xff0c;然后需要将其绘制。这组数据可能是txt格式的&#xff0c;也可能…

uni-app:实现点击按钮,进行数据累加展示(解决数据过多,导致出错)

效果 代码 核心代码 一、标签显示 <!-- 加载更多 --> <view class"load_more" v-if"info.length > pageNum * pageSize" tap"loadMore">加载更多 </view> v-if"info.length > pageNum * pageSize"&#xf…

远景智能PMO负责人严晓婷受邀为第十二届中国PMO大会演讲嘉宾

上海远景科创智能科技有限公司PMO负责人严晓婷女士受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;能源物联网产品标准项目和非标准项目的并行管理。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1…

教雅川学缠论07-中枢实战众泰汽车000980

本文实战众泰汽车 下面是2023年11月14-2023年8月8众泰汽车日K图 先画日K 接下来处理包含&#xff0c;就变成下面这个样子 下面在套上缠论的理论&#xff0c;未来股价的走势应该是红色椭圆形虚线里面的样子 好了&#xff0c;文章就到这里&#xff0c;如果众泰最终不是这个走势…

网页版Java(Spring/Spring Boot/Spring MVC)五子棋项目(四)对战模块

网页版Java&#xff08;Spring/Spring Boot/Spring MVC&#xff09;五子棋项目&#xff08;四&#xff09;对战模块 一、约定前后端交互接口1. 建立连接接口2. 针对落子的请求和响应 二、实现前端页面三、实现后端1. 当用户进入房间&#xff0c;更新用户状态 OnlineUserManager…

W5500-EVB-PICO作为TCP Client 进行数据回环测试(五)

前言 上一章我们用W5500-EVB-PICO开发板通过DNS解析www.baidu.com&#xff08;百度域名&#xff09;成功得到其IP地址&#xff0c;那么本章我们将用我们的开发板作为客户端去连接服务器&#xff0c;并做数据回环测试&#xff1a;收到服务器发送的数据&#xff0c;并回传给服务器…

FFmpeg 编码详细流程

介绍 FFmpeg的 libavcodec 模块完成音视频多媒体的编解码模块。FFmpeg 本身不具有音视频编码的功能和底层能力&#xff0c;只是对各类第三方的编码器API 进行封装调用。老版本的 FFmpeg 将avcodec_encode_video2()作为视频的解码函数 API&#xff0c;将avcodec_encode_audio2(…

IO模型-信号驱动IO

linux内核中存在一个信号SIGIO&#xff0c;这个信号就是用于实现信号驱动IO的。当应用程序中想要以信号驱动IO的模型读写硬件数据时&#xff0c;首先注册一个SIGIO信号的信号处理函数,当硬件数据就绪&#xff0c;硬件会发起一个中断&#xff0c;在硬件的中断处理函数中向当前进…

css-4:元素水平垂直居中的方法有哪些?如果元素不定宽高呢?

1、背景 在开发中&#xff0c;经常遇到这个问题&#xff0c;即让某个元素的内容在水平和垂直方向上都居中&#xff0c;内容不仅限于文字&#xff0c;可能是图片或其他元素。 居中是一个非常基础但又是非常重要的应用场景&#xff0c;实现居中的方法存在很多&#xff0c;可以将这…

解决 Android Studio 的 Gradle 面板上只有关于测试的 task 的问题

文章目录 问题描述解决办法 笔者出问题时的运行环境&#xff1a; Android Studio Flamingo | 2022.2.1 Android SDK 33 Gradle 8.0.1 JDK 17 问题描述 笔者最近发现一个奇怪的事情。笔者的 Android Studio 的 Gradle 面板上居然除了用于测试的 task 之外&#xff0c;其它什…

centos8.5本地yum源报错

在下载文件出现以下错误 [rootserver ~]# yum install gcc Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use subscription-manager to register. RHEL8.5-BaseOS …

【对于一维信号的匹配】对一个一维(时间)信号y使用自定义基B执行匹配追踪(MP)研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

冠达管理:大跳水!美国又要下黑手!3300亿巨头突然死亡,疯抢锂矿

美国又要下“黑手”。 据环球网征引路透社音讯&#xff0c;美国政府高级官员泄漏&#xff0c;白宫当地时间9日将具体阐明约束美国在华出资灵敏技能的方案&#xff0c;并要求将其他有关出资奉告政府。 美股商场上演了一场大败局。当地时间8月9日美股盘中&#xff0c;全球同享工…

如何给Linux开启swap虚拟内存

查看系统内存资源 free -h 创建swap分区 dd if/dev/zero of/swapfile bs1024 count4194304dev/zero&#xff1a;是Linux的一种特殊字符设备(输入设备)&#xff0c;可以用来创建一个指定长度用于初始化的空文件&#xff0c;如临时交换文件&#xff0c;该设备无穷尽地提供0&…

Linux下C/C++的gdb工具与Python的pdb工具常见用法之对比

1、gdb和pdb分别是什么&#xff1f; 1.1、gdb GDB&#xff08;GNU Debugger&#xff09;是一个功能强大的命令行调试工具&#xff0c;由GNU项目开发&#xff0c;用于调试C、C等编程语言的程序。它在多个操作系统中都可以使用&#xff0c;包括Linux、MacOS和Windows&#xff0…

大数据Flink(五十八):Flink on Yarn的三种部署方式介绍

文章目录 Flink on Yarn的三种部署方式介绍 一、​​​​​​​Session模式

ChatGLM2-6B在windows下的部署

2023-08-10 ChatGLM2-6B在windows下的部署 一、部署环境 1、Windows 10 专业版&#xff0c; 64位&#xff0c;版本号&#xff1a;22H2&#xff0c;内存&#xff1a;32GB 2、已安装CUDA11.3 3、已安装Anaconda3 64bit版本 4、有显卡NVIDIA GeForce RTX 3060 Laptop GPU …

【Git】Git切换地址

如何切换git代码地址&#xff1f; 1、查看当前远程 url git remote -v执行命令后&#xff0c;可以看见当前有2个URL。 远程 URL 在一般情况下有两个&#xff0c;分别是 fetch 和 push。 fetch URL 是用于从远程仓库获取最新版本的数据。当您运行 git fetch 命令时&#xf…

【EI/SCOPUS检索】第三届新媒体发展与现代化教育国际学术会议(NMDME 2023)

第三届新媒体发展与现代化教育国际学术会议&#xff08;NMDME 2023&#xff09; The 3rd International Conference on New Media Development and Modernized Education 第三届新媒体发展与现代化教育国际学术会议(NMDME 2023)将于2023年10月13-15日于西安召开。会议旨在为新…
最新文章