并行FIR滤波器

FIR 滤波器原理

FIR 滤波器是有限长单位冲击响应滤波器,又称为非递归型滤波器。FIR 滤波器具有严格的线性相频特性,同时其单位响应是有限长的,因而是稳定的系统。

FIR 滤波器本质上就是输入信号与单位冲击响应函数的卷积,表达式如下:

在这里插入图片描述

直接型结构如下:

在这里插入图片描述
FIR 滤波器有如下几个特性:

  • (1) 响应是有限长序列。
  • (2) 系统函数在 |z| > 0 处收敛,极点全部在 z=0 处,属于因果系统。
  • (3) 结构上是非递归的,没有输出到输入的反馈。
  • (4) 输入信号相位响应是线性的,因为响应函数 h(n) 系数是对称的。
  • (5) 输入信号的各频率之间,相对相位差也是固定不变的。
  • (6) 时域卷积等于频域相乘,因此该卷积相当于筛选频谱中各频率分量的增益倍数。某些频率分量保留,某些频率分量衰减,从而实现滤波的效果。

并行 FIR 滤波器设计

设计说明

输入频率为 7.5 MHz 和 250 KHz 的正弦波混合信号,经过 FIR 滤波器后,高频信号 7.5MHz 被滤除,只保留 250KHz 的信号。设计参数如下:

输入频率:       7.5MHz 和 250KHz
采样频率:       50MHz
阻带:           1MHz ~ 6MHz
阶数:           15(N-1=15)

由 FIR 滤波器结构可知,阶数为 15 时,FIR 的实现需要 16 个乘法器,15 个加法器和 15 组延时寄存器。为了稳定第一拍的数据,可以再多用一组延时寄存器,即共用 16 组延时寄存器。由于 FIR 滤波器系数的对称性,乘法器可以少用一半,即共使用 8 个乘法器。类似下面结构:

在这里插入图片描述

并行设计,就是在一个时钟周期内对 16 个延时数据同时进行乘法、加法运算,然后在时钟驱动下输出滤波值。这种方法的优点是滤波延时短,但是对时序要求比较高。

并行设计

FIR 滤波器系数由 matlab 生成。

代码以功能实现为目标

/***********************************************************
>> V : Fs:50Mhz, fstop:1Mhz-6Mhz, order: 15
************************************************************/
`define SAFE_DESIGNmodule fir_parallel    (input                rstn,  //复位,低有效input                clk,   //工作频率,即采样频率input                en,    //输入数据有效信号input        [11:0]  xin,   //输入混合频率的信号数据output               valid, //输出数据有效信号output       [28:0]  yout   //输出数据,低频信号,即250KHz);//data en delayreg [3:0]            en_r ;always @(posedge clk or negedge rstn) beginif (!rstn) beginen_r[3:0]      <= 'b0 ;endelse beginen_r[3:0]      <= {en_r[2:0], en} ;endend//(1) 16 组移位寄存器reg        [11:0]    xin_reg[15:0];reg [3:0]            i, j ;always @(posedge clk or negedge rstn) beginif (!rstn) beginfor (i=0; i<15; i=i+1) beginxin_reg[i]  <= 12'b0;endendelse if (en) beginxin_reg[0] <= xin ;for (j=0; j<15; j=j+1) beginxin_reg[j+1] <= xin_reg[j] ; //周期性移位操作endendend//Only 8 multipliers needed because of the symmetry of FIR filter coefficient//(2) 系数对称,16个移位寄存器数据进行首位相加reg        [12:0]    add_reg[7:0];always @(posedge clk or negedge rstn) beginif (!rstn) beginfor (i=0; i<8; i=i+1) beginadd_reg[i] <= 13'd0 ;endendelse if (en_r[0]) beginfor (i=0; i<8; i=i+1) beginadd_reg[i] <= xin_reg[i] + xin_reg[15-i] ;endendend//(3) 8个乘法器// 滤波器系数,已经过一定倍数的放大wire        [11:0]   coe[7:0] ;assign coe[0]        = 12'd11 ;assign coe[1]        = 12'd31 ;assign coe[2]        = 12'd63 ;assign coe[3]        = 12'd104 ;assign coe[4]        = 12'd152 ;assign coe[5]        = 12'd198 ;assign coe[6]        = 12'd235 ;assign coe[7]        = 12'd255 ;wire        [24:0]   mout[7:0];`ifdef SAFE_DESIGN//流水线式乘法器wire [7:0]          valid_mult ;genvar              k ;generatefor (k=0; k<8; k=k+1) beginmult_man #(13, 12)u_mult_paral          (.clk        (clk),.rstn       (rstn),.data_rdy   (en_r[1]),.mult1      (add_reg[k]),.mult2      (coe[k]),.res_rdy    (valid_mult[k]), //所有输出使能完全一致  .res        (mout[k]));endendgeneratewire valid_mult7     = valid_mult[7] ;`else//如果对时序要求不高,可以直接用乘号always @(posedge clk or negedge rstn) beginif (!rstn) beginfor (i=0 ; i<8; i=i+1) beginmout[i]     <= 25'b0 ;endendelse if (en_r[1]) beginfor (i=0 ; i<8; i=i+1) beginmout[i]     <= coe[i] * add_reg[i] ;endendendwire valid_mult7 = en_r[2];
`endif//(4) 积分累加,8组25bit数据 -> 1组 29bit 数据//数据有效延时reg [3:0]            valid_mult_r ;always @(posedge clk or negedge rstn) beginif (!rstn) beginvalid_mult_r[3:0]  <= 'b0 ;endelse beginvalid_mult_r[3:0]  <= {valid_mult_r[2:0], valid_mult7} ;endend`ifdef SAFE_DESIGN//加法运算时,分多个周期进行流水,优化时序reg        [28:0]    sum1 ;reg        [28:0]    sum2 ;reg        [28:0]    yout_t ;always @(posedge clk or negedge rstn) beginif (!rstn) beginsum1   <= 29'd0 ;sum2   <= 29'd0 ;yout_t <= 29'd0 ;endelse if(valid_mult7) beginsum1   <= mout[0] + mout[1] + mout[2] + mout[3] ;sum2   <= mout[4] + mout[5] + mout[6] + mout[7] ;yout_t <= sum1 + sum2 ;endend`else//一步计算累加结果,但是实际中时序非常危险reg signed [28:0]    sum ;reg signed [28:0]    yout_t ;always @(posedge clk or negedge rstn) beginif (!rstn) beginsum    <= 29'd0 ;yout_t <= 29'd0 ;endelse if (valid_mult7) beginsum    <= mout[0] + mout[1] + mout[2] + mout[3] + mout[4] + mout[5] + mout[6] + mout[7];yout_t <= sum ;endend
`endifassign yout  = yout_t ;assign valid = valid_mult_r[0];endmodule

testbench

testbench 如下,主要功能就是不间断连续的输入 250KHz 与 7.5MHz 的正弦波混合信号数据。输入的混合信号数据也由 matlab 生成。

`timescale 1ps/1psmodule test ;//inputreg          clk ;reg          rst_n ;reg          en ;reg [11:0]   xin ;//outputwire         valid ;wire [28:0]  yout ;parameter    SIMU_CYCLE   = 64'd2000 ;  //50MHz 采样频率parameter    SIN_DATA_NUM = 200 ;       //仿真周期//=====================================
// 50MHz clk generatinglocalparam   TCLK_HALF     = 10_000;initial beginclk = 1'b0 ;forever begin# TCLK_HALF ;clk = ~clk ;endend//============================
//  reset and finishinitial beginrst_n = 1'b0 ;# 30   rst_n = 1'b1 ;# (TCLK_HALF * 2 * SIMU_CYCLE) ;$finish ;end//=======================================
// read signal data into registerreg          [11:0] stimulus [0: SIN_DATA_NUM-1] ;integer      i ;initial begin$readmemh("cosx0p25m7p5m12bit.txt", stimulus) ;//windows下似乎只能使用绝对路径i = 0 ;en = 0 ;xin = 0 ;# 200 ;forever begin@(negedge clk) beginen          = 1'b1 ;xin         = stimulus[i] ;if (i == SIN_DATA_NUM-1) begin  //周期送入数据控制i = 0 ;endelse begini = i + 1 ;endendendendfir_parallel u_fir_paral (.xin         (xin),.clk         (clk),.en          (en),.rstn        (rst_n),.valid       (valid),.yout        (yout));endmodule

仿真结果

由下图仿真结果可知,经过 FIR 滤波器后的信号只有一种低频率信号(250KHz),高频信号(7.5MHz)被滤除了。而且输出波形是连续的,能够持续输出。

在这里插入图片描述

在这里插入图片描述

matlab 使用

生成 FIR 滤波器系数

打开 matlab,在命令窗口输入命令: fdatool。

然后会打开如下窗口,按照 FIR 滤波器参数进行设置。

这里选择的 FIR 实现方法是最小二乘法(Least-squares),不同的实现方式滤波效果也不同,对应的滤波器系数也不同。

在这里插入图片描述

点击 File -> Export

将滤波器参数输出,存到变量 coef 中,如下图所示。

在这里插入图片描述

此时 coef 变量应该是浮点型数据。对其进行一定倍数的相乘扩大,然后取其近似的定点型数据作为设计中的 FIR 滤波器参数。这里取扩大倍数为 2048,结果如下所示。

在这里插入图片描述

生成输入的混合信号

利用 matlab 生成混合的输入信号参考代码如下。

信号为无符号定点型数据,位宽宽度为 12bit,存于文件 cosx0p25m7p5m12bit.txt


```matlab
clear all;close all;clc;
%=======================================================
% generating a cos wave data with txt hex format
%=======================================================fc          = 0.25e6 ;      % 中心频率
fn          = 7.5e6 ;       % 杂波频率
Fs          = 50e6 ;        % 采样频率
T           = 1/fc ;        % 信号周期
Num         = Fs * T ;      % 周期内信号采样点数
t           = (0:Num-1)/Fs ;      % 离散时间
cosx        = cos(2*pi*fc*t) ;    % 中心频率正弦信号
cosn        = cos(2*pi*fn*t) ;    % 杂波信号
cosy        = mapminmax(cosx + cosn) ;     %幅值扩展到(-1,1) 之间
cosy_dig    = floor((2^11-1) * cosy + 2^11) ;     %幅值扩展到 0~4095
fid         = fopen('cosx0p25m7p5m12bit.txt', 'wt') ;  %写数据文件
fprintf(fid, '%x\n', cosy_dig) ;
fclose(fid) ;%时域波形
figure(1);
subplot(121);plot(t,cosx);hold on ;
plot(t,cosn) ;
subplot(122);plot(t,cosy_dig) ;%频域波形
fft_cosy    = fftshift(fft(cosy, Num)) ;
f_axis      = (-Num/2 : Num/2 - 1) * (Fs/Num) ;
figure(5) ;
plot(f_axis, abs(fft_cosy)) ;

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【马蹄集】第二十二周——进位制与字符串专题

进位制与字符串专题 目录 MT2179 01操作MT2182 新十六进制MT2172 萨卡兹人MT2173 回文串等级MT2175 五彩斑斓的串 MT2179 01操作 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目描述 刚学二进制的小码哥对加减乘除还不熟&#xff0c;他…

剑指 Offer 61. 扑克牌中的顺子

题目描述 从若干副扑克牌中随机抽 5 张牌&#xff0c;判断是不是一个顺子&#xff0c;即这5张牌是不是连续的。2&#xff5e;10为数字本身&#xff0c;A为1&#xff0c;J为11&#xff0c;Q为12&#xff0c;K为13&#xff0c;而大、小王为 0 &#xff0c;可以看成任意数字。A 不…

Tubi 前端测试:迁移 Enzyme 到 React Testing Library

前端技术发展迅速&#xff0c;即便不说是日新月异&#xff0c;每年也都推出新框架和新技术。Tubi 的产品前端代码仓库始建于 2015 年&#xff0c;至今 8 年有余。可喜的是&#xff0c;多年来紧随 React 社区的发展&#xff0c;Tubi 绝大多数的基础框架选型都遵循了社区流行的最…

翻转二叉树

声明 该系列文章仅仅展示个人的解题思路和分析过程&#xff0c;并非一定是优质题解&#xff0c;重要的是通过分析和解决问题能让我们逐渐熟练和成长&#xff0c;从新手到大佬离不开一个磨练的过程&#xff0c;加油&#xff01; 原题链接 翻转二叉树备战技术面试&#xff1f;…

C#与C++交互(2)——ANSI、UTF8、Unicode文本编码

【前言】 我们知道计算机上只会存储二进制的数据&#xff0c;无论文本、图片、音频、视频等&#xff0c;当我们将其保存在计算机上时&#xff0c;都会被转成二进制的。我们打开查看的时候&#xff0c;二进制数据又被转成我们看得懂的信息。如何将计算机上的二进制数据转为我们…

EFLFK——ELK日志分析系统+kafka+filebeat架构

环境准备 node1节点192.168.40.16elasticsearch2c/4Gnode2节点192.168.40.17elasticsearch2c/4GApache节点192.168.40.170logstash/Apache/kibana2c/4Gfilebeat节点192.168.40.20filebeat2c/4G https://blog.csdn.net/m0_57554344/article/details/132059066?spm1001.2014.30…

网络安全的相关知识点

网络安全威胁类型&#xff1a; 1.窃听&#xff1a;广播式网络系统。 2.假冒 3.重放&#xff1a;重复一份报文或者报文的一部分&#xff0c;以便产生一个被授权的效果。 4.流量分析 5.数据完整性破坏 6.拒绝服务 7.资源的非授权使用 8.陷门和特洛伊木马&#xff1a;木马病毒有客…

2023年国赛数学建模思路 - 案例:ID3-决策树分类算法

文章目录 0 赛题思路1 算法介绍2 FP树表示法3 构建FP树4 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模…

vue-element-admin动态菜单(后台获取)

vue-element-admin动态菜单&#xff08;后台获取&#xff09;&#xff0c;此教程面向纯小白攻略&#xff0c;不要嫌我啰嗦&#xff0c;翻到自己需要的地方即可 前提 vue-element-admin官网&#xff1a; vue-element-admin (gitee.io) vue-element-admin页面展示&#xff1a;…

Redis复制

在Redis中&#xff0c;用户可以通过执行SLAVEOF命令或者设置slaveof选项&#xff0c;让一个服务器去复制(replicate) 另一个服务器&#xff0c;我们称呼被复制的服务器为主服务器(master)&#xff0c;而对主服务器进行复制的服务器则被称为从服务器(slave)&#xff0c;如下图所…

什么是伪类选择器?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 伪类选择器⭐ 一些常见的伪类选择器示例&#xff1a;:hover:active:focus:nth-child(n):first-child 和 :last-child ⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何…

关于Java中synchronized的实现原理

并发编程的三个理念 原子性&#xff1a;一个操作要么全部完成&#xff0c;要么全部失败。可见性&#xff1a;当一个线程对共享变量进行修改后&#xff0c;其他线程也应立刻看到。有序性&#xff1a;程序按照顺序执行 synchronized基本使用 修饰静态方法&#xff0c;锁的是类…