您的位置:首页 > 科技 > IT业 > 基于FPGA的任意点滑动平均(滑动窗长度和数据位宽参数化,例化时参数可设置)

基于FPGA的任意点滑动平均(滑动窗长度和数据位宽参数化,例化时参数可设置)

2024/11/17 17:47:05 来源:https://blog.csdn.net/xxqlover/article/details/139511777  浏览:    关键词:基于FPGA的任意点滑动平均(滑动窗长度和数据位宽参数化,例化时参数可设置)

目录

  • 1.前言
  • 2.原理
  • 3.举例说明
  • 4.Matlab实现
  • 5.FPGA实现滑动平均

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

1.前言

对于一维信号,我们可以使用类似移动平均滤波(Moving Average Filtering)实现denoising。Moving Average Filtering 是一种简单的信号滤波算法,用于减小信号中的噪声或去除高频成分,从而平滑信号。它基于对信号中一定窗口内数据的平均值进行计算。移动平均滤波可以平滑信号,但对快速变化的信号可能响应较慢。

2.原理

给定一个包含 N 个样本的信号序列$ x [ n ] $,其中 n 是样本的索引(从 0 到 N-1)。移动平均滤波通过在信号序列上滑动一个固定长度为 M 的窗口,并计算窗口内样本的平均值来进行滤波。

对于滑动窗口的每个位置 k,滤波后的输出 y[k] 可以通过以下公式计算:
y [ k ] = x [ k ] + x [ k − 1 ] + x [ k − 2 ] + . . . + x [ k − M + 1 ] M y[k]= x[k]+x[k−1]+x[k−2]+...+x[k−M+1] \over M My[k]=x[k]+x[k1]+x[k2]+...+x[kM+1]

其中,$x [ k ] $表示信号序列中索引为 k 的样本值。公式中的 $1 / M $ 是归一化因子,用于平均化窗口内的样本值。

移动平均滤波的核心思想是利用窗口内多个样本的平均值来代表当前样本的值,从而减小随机噪声或高频成分对信号的影响。滑动窗口的大小 M 决定了平滑的程度,较大的窗口可以更有效地平滑信号,但可能会导致滞后响应;较小的窗口可以更快地响应信号的变化,但平滑效果可能较差。

需要注意的是,移动平均滤波是一种线性滤波方法,主要适用于平稳信号或缓慢变化的信号。对于包含快速变化的信号或脉冲信号,移动平均滤波可能导致平滑效果不佳或信号失真。在实际应用中,根据具体的信号特性和需求,可以选择不同的滤波方法以获得更好的结果。

3.举例说明

比方说,当我们有一个包含噪声的信号序列时,例如:
x = [ 2 , 4 , 3 , 7 , 6 , 5 , 10 , 8 , 9 , 12 ] x=[2,4,3,7,6,5,10,8,9,12] x=[2,4,3,7,6,5,10,8,9,12]
我们可以使用移动平均滤波来平滑信号并减小噪声的影响。假设我们选择一个窗口大小为3,即每次计算三个样本的平均值。
第一个输出样本为:
y [ 0 ] = ( 1 / 3 ) ∗ ( 2 + 4 + 3 ) = 3 y[0]=(1/3)∗(2+4+3)=3 y[0]=(1/3)(2+4+3)=3
第二个输出样本为:
y [ 1 ] = ( 1 / 3 ) ∗ ( 4 + 3 + 7 ) = 4.67 y[1]=(1/3)∗(4+3+7)=4.67 y[1]=(1/3)(4+3+7)=4.67
以此类推,我们可以继续计算后续输出样本。如果数学比较好的朋友,此刻大概能看出这其实就是卷积。
而卷机核函数,就是长度为N,元素值为 1 N \frac{1}{N} N1。所以,我们可以使用Matlab的filter函数来实现Moving Average Filtering(滑动平均)。

4.Matlab实现

网上找了一段别人采集的原始信号数据如下:

y0 =列 1 至 160.0300   -1.4600   -0.2600   -0.4700   -1.4600   -0.0600   -0.4700   -1.2700    0.1500   -0.4700   -1.4700   -0.0100   -0.4700   -1.2700    0.1700   -0.6300列 17 至 32-1.3700    0.1500   -0.8800   -1.0700    0.2500   -0.8800   -1.2700    0.2500   -0.8800   -1.0700    0.4000   -1.0800   -1.0700    0.1100   -1.2800   -0.8700列 33 至 480.2100   -1.2800   -0.9400    0.3600   -1.2800   -0.4600    0.2500   -1.2800   -0.4600    0.2300   -1.2300   -0.4600   -0.0700   -1.3100   -0.4600    0.2300列 49 至 64-1.3100   -0.4600    0.1300   -1.4900   -0.4600   -0.4700   -1.3900   -0.4600   -0.4700   -1.4400   -0.3600    0.0300   -1.4400   -0.2600    0.0300   -1.5600列 65 至 80-0.2600   -0.4700   -1.4100   -0.2600   -0.4700   -1.6000   -0.2600   -0.4700   -1.2700    0.0700   -0.4700   -1.4200    0.1500   -0.8800   -1.2700    0.3000列 81 至 96-1.0800   -1.0700    0.1800   -1.3400   -0.4600    1.8600    6.6500    9.0600    8.0300    7.1400    7.7900    4.7900    2.8800    3.0800    1.5500    1.2600列 97 至 1121.9600    0.4400    0.9600    1.4500   -0.0900    1.1600    0.9400   -0.2600    1.1600   -0.4700   -1.2700    0.1000   -1.2800   -0.4600    0.1800   -1.3100列 113 至 128-0.4600   -0.1200   -1.4900   -0.0100   -0.6800   -1.2700    0.0400   -1.0800   -0.4600    0.2300   -1.2800   -0.4600   -0.4700   -1.4600   -0.3100   -0.4700列 129 至 144-1.4500    0.1500   -0.5800   -1.4700    0.1500   -0.8800   -1.2700    0.2500   -0.8800   -1.2700    0.3500   -1.0800   -1.1700    0.2200   -1.0800   -1.0700列 145 至 1600.1100   -1.2800   -1.0700    0.4000   -1.2800   -2.4900   -7.3600  -11.0100   -9.9800   -7.3900   -9.1900   -6.9400   -4.0700   -4.6000   -3.7000   -1.9800列 161 至 176-3.3100   -2.6900   -1.3000   -2.7000   -2.4900   -1.1300   -2.5000   -2.0800   -0.6800   -1.6900   -0.4600    0.0300   -1.3900   -0.4600    0.2100   -1.3100列 177 至 192-0.4600    0.0800   -1.3900   -0.7700    0.1300   -1.4900   -0.4600    0.2300   -1.4900   -0.4600   -0.0200   -1.4900   -0.4100    0.1800   -1.4600   -0.4600列 193 至 208-0.4700   -1.4200   -0.2600   -0.4700   -1.4400   -0.2600   -0.4700   -1.5500   -0.0100   -0.5800   -1.4200   -0.4600   -0.4700   -1.4500   -0.0600   -0.5000列 209 至 224-1.2700    0.1500   -0.8800   -1.2700    0.3500   -1.2800    0.5500    7.4800    8.3300    8.7600    7.8300    6.8300    5.7200    3.4800    1.9700    2.5400列 225 至 2401.0200    1.3600    1.8600    0.3400    0.9600    0.9400   -0.0600    1.1600    0.3400   -0.0600    0.5100   -1.2800   -0.4600    0.1300   -1.4400   -0.2600列 241 至 256-0.4700   -1.4500    0.0600   -0.7000   -1.2200    0.3200   -1.1800   -0.4600    0.0700   -1.5400   -0.3100   -0.4700   -1.2700    0.1500   -0.9800   -1.1700列 257 至 2720.2600   -1.2300   -0.4600   -0.0700   -1.3400   -0.4600   -0.0700   -1.3000   -0.1600   -0.4700   -1.4900   -0.2600   -0.4700   -1.4500   -0.0600   -0.4700列 273 至 288-1.4700    0.0400   -0.6800   -1.4200    0.0700   -0.8800   -2.6100   -7.1500  -10.3000  -10.3400   -7.3000   -8.5800   -7.7500   -4.1100   -4.3200   -3.9100列 289 至 304-1.6300   -3.0100   -3.1000   -1.2100   -2.6000   -2.4900   -1.0600   -2.3000   -2.0800   -0.6600   -1.4900   -1.1700    0.1200   -1.2800   -0.4600    0.3100列 305 至 320-1.3400   -0.4600    0.0600   -1.4900   -0.4600   -0.0700   -1.3900   -0.4100   -0.4700   -1.4900   -0.4600   -0.4700   -1.4400   -0.3600   -0.1200   -1.4600列 321 至 331-0.0600   -0.4700   -1.4200   -0.2100   -0.4700   -1.4700   -0.0600   -0.5300   -1.2700    0.1700   -0.6800

为了直观,下面简单的画一下他的图:

y0=[0.03	-1.46	-0.26	-0.47	-1.46	-0.06	-0.47	-1.27	0.15	-0.47	-1.47	-0.01	-0.47	-1.27	0.17	-0.63	-1.37	0.15	-0.88	-1.07	0.25	-0.88	-1.27	0.25	-0.88	-1.07	0.4	-1.08	-1.07	0.11	-1.28	-0.87	0.21	-1.28	-0.94	0.36	-1.28	-0.46	0.25	-1.28	-0.46	0.23	-1.23	-0.46	-0.07	-1.31	-0.46	0.23	-1.31	-0.46	0.13	-1.49	-0.46	-0.47	-1.39	-0.46	-0.47	-1.44	-0.36	0.03	-1.44	-0.26	0.03	-1.56	-0.26	-0.47	-1.41	-0.26	-0.47	-1.6	-0.26	-0.47	-1.27	0.07	-0.47	-1.42	0.15	-0.88	-1.27	0.3	-1.08	-1.07	0.18	-1.34	-0.46	1.86	6.65	9.06	8.03	7.14	7.79	4.79	2.88	3.08	1.55	1.26	1.96	0.44	0.96	1.45	-0.09	1.16	0.94	-0.26	1.16	-0.47	-1.27	0.1	-1.28	-0.46	0.18	-1.31	-0.46	-0.12	-1.49	-0.01	-0.68	-1.27	0.04	-1.08	-0.46	0.23	-1.28	-0.46	-0.47	-1.46	-0.31	-0.47	-1.45	0.15	-0.58	-1.47	0.15	-0.88	-1.27	0.25	-0.88	-1.27	0.35	-1.08	-1.17	0.22	-1.08	-1.07	0.11	-1.28	-1.07	0.4	-1.28	-2.49	-7.36	-11.01	-9.98	-7.39	-9.19	-6.94	-4.07	-4.6	-3.7	-1.98	-3.31	-2.69	-1.3	-2.7	-2.49	-1.13	-2.5	-2.08	-0.68	-1.69	-0.46	0.03	-1.39	-0.46	0.21	-1.31	-0.46	0.08	-1.39	-0.77	0.13	-1.49	-0.46	0.23	-1.49	-0.46	-0.02	-1.49	-0.41	0.18	-1.46	-0.46	-0.47	-1.42	-0.26	-0.47	-1.44	-0.26	-0.47	-1.55	-0.01	-0.58	-1.42	-0.46	-0.47	-1.45	-0.06	-0.5	-1.27	0.15	-0.88	-1.27	0.35	-1.28	0.55	7.48	8.33	8.76	7.83	6.83	5.72	3.48	1.97	2.54	1.02	1.36	1.86	0.34	0.96	0.94	-0.06	1.16	0.34	-0.06	0.51	-1.28	-0.46	0.13	-1.44	-0.26	-0.47	-1.45	0.06	-0.7	-1.22	0.32	-1.18	-0.46	0.07	-1.54	-0.31	-0.47	-1.27	0.15	-0.98	-1.17	0.26	-1.23	-0.46	-0.07	-1.34	-0.46	-0.07	-1.3	-0.16	-0.47	-1.49	-0.26	-0.47	-1.45	-0.06	-0.47	-1.47	0.04	-0.68	-1.42	0.07	-0.88	-2.61	-7.15	-10.3	-10.34	-7.3	-8.58	-7.75	-4.11	-4.32	-3.91	-1.63	-3.01	-3.1	-1.21	-2.6	-2.49	-1.06	-2.3	-2.08	-0.66	-1.49	-1.17	0.12	-1.28	-0.46	0.31	-1.34	-0.46	0.06	-1.49	-0.46	-0.07	-1.39	-0.41	-0.47	-1.49	-0.46	-0.47	-1.44	-0.36	-0.12	-1.46	-0.06	-0.47	-1.42	-0.21	-0.47	-1.47	-0.06	-0.53	-1.27	0.17	-0.68];
figure
plot(y0)
title("原始信号")

采集的原始信号

使用Matlab的filter函数进行4点的滑动平均:

%% Matlab仿真
windowSize = 3; %滑动窗点数
b = (1/windowSize)*ones(1,windowSize);
a = 1;
y1 = filter(b,a,y0);figure
subplot(3,1,1)
plot(y0)
title("原始信号")subplot(3,1,2)
plot(y1)
title("滑动平均滤波后")subplot(3,1,3)
plot(y0)
hold on
plot(y1)
title("对比")

Matlab仿真的滑动平均

5.FPGA实现滑动平均

模块的输入输出框图如下所示:

输入输出框图

模块功能:对输入信号取滑动平均值。例化调用格式如下:

MovAvg 
#(  .N(N),//滑动平均点数,2的n次方.WIDTH(WIDTH))数据位宽
u1(.clk     	(clk)           ,.rst_n   	(rst_n)         ,.din_vaild	(din_vaild)		,	.din     	(din)           ,.dout  		(dout)			,.dout_vaild	(dout_vaild)
);

参数N表示求N个点的平均值,参数WIDTH控制输入信号位宽,可以在例化调用的时候配置参数。

配置参数为16点滑动平均,位宽为8,使用依次递增1的数据进行测试:

16点滑动平均

配置参数为4点滑动平均,位宽为8,使用上面的数据输入进行测试,按照如下代码将数据存储到txt文件里面:

q = quantizer('fixed','round','saturate',[8,3]);%复数以8位定点数形式进行输出,格式为:1位符号位,4位整数位,3位小数位,负数以补码形式表示。
y0_q = num2hex(q,y0);%量化fid= fopen([PATH,'test_data.txt'],'w');
fprintf(fid,'%c%c\r\n',y0_q');

整体仿真截图

局部仿真放大图

对上面第4小节,Matlab实现的4点滑动平均进行对比:

Matlab仿真和FPGA输出结果对比

测试激励代码(注释部分为配置参数为16点滑动平均,位宽为8,使用依次递增1的数据进行测试):

`timescale 1ns / 1psmodule MovAvg_tb;
parameter		T = 20;//仿真时钟周期
parameter		NUM  = 331			;//测试数据个数
parameter		N = 4				;//滑动平均点数,2的n次方
parameter		WIDTH = 8			;//数据位宽
parameter		PATH = "D:/FPGA/FPGA_university/gra_stu_FPGA_class/MovAvg/";//文件路径
reg             clk					;
reg             rst_n				;
reg				din_vaild			;
reg  signed[7:0]   din				;
wire signed[7:0]   dout				;
wire			dout_vaild			;
reg   	[7:0]	test_data [NUM-1:0]	;
integer			i					;
integer signed	data_out			;
MovAvg #(.N(N),.WIDTH(WIDTH))
u1(.clk     	(clk)           ,.rst_n   	(rst_n)         ,.din_vaild	(din_vaild)		,	.din     	(din)           ,.dout  		(dout)			,.dout_vaild	(dout_vaild)
);
always #(T/2) clk = ~clk;
initial beginrst_n = 1'b0;din_vaild = 1'b0;clk = 1'b1;$readmemh({PATH,"test_data.txt"},test_data,0,NUM-1);data_out  =  $fopen({PATH,"data_out.txt"});#(T*5)rst_n = 1'b1;din_vaild = 1'b1;//test_data测试数据输入for(i=0;i<NUM;i=i+1)begindin = test_data[i];#T;enddin_vaild = 1'b0;
end//数据存储,由于从第N个点开始有效,输出会少N-1个数据
always@(posedge clk)
beginif(dout_vaild)begin$fdisplay(data_out,"%d",dout);end
end//输入为连续累加1数据的测试
/* always @(posedge clk or negedge rst_n)if (!rst_n)din <= 8'b0;elsedin <= din + 1'b1; */endmodule

下载工程源码链接:https://mp.weixin.qq.com/s?__biz=MzkxNjM0NDk2Nw==&mid=2247486083&idx=1&sn=e942deb7b27b2b7a3231751f803b158c&chksm=c150136bf6279a7d90128972cda2b7075a63d25fa3ce839c31b68ec66731d07478f4555dd6e4#rd
也可以选择此跳转

微信公众号获取更多FPGA相关源码:
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com