基于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 至 16

    0.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 至 48

    0.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 至 112

    1.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 至 160

    0.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 至 240

    1.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 至 272

    0.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 / 1ps

module 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 begin
    rst_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)begin
		din = test_data[i];
		#T;
	end
	din_vaild = 1'b0;
end

//数据存储,由于从第N个点开始有效,输出会少N-1个数据
always@(posedge clk)
begin
  if(dout_vaild)
    begin
      $fdisplay(data_out,"%d",dout);
    end
end

//输入为连续累加1数据的测试
/* always @(posedge clk or negedge rst_n)
    if (!rst_n)
        din <= 8'b0;
    else
        din <= din + 1'b1; */

endmodule

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

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

  • 56
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值