FIR数字滤波器的FPGA实现(vivodo平台)

在现代通信信号处理领域中,信息传输的安全性和保密性变得越来越重要。数字信号是数据经采样、量化、编码后所得到的离散的序列样值。在通信系统中,若信道中传输的是数字信号则称为数字通信。在以往的模拟通信中,模拟滤波器无法克服电压漂移、温度漂移和噪声等问题对自身的影响,从而带来了许多误差和不稳定因素,但是在数字通讯中数字滤波器既有稳定性搞、精度高、设计灵活、不需要阻抗匹配等优点。

数字滤波技术是数字信号分析、处理技术的重要分支。无论是信号的获取、传输,还是信号的处理和交换都离不开滤波技术,它对信号安全可靠和有效灵活地传输是至关重要的。在所有的电子系统中,使用最多技术最复杂的要算数字滤波器了。数字滤波器的优劣直接决定产品的优劣。

本文将用matlab与vivodo联合实现FIR数字滤波器

首先在matlab中直接生成量化后的混合波数据:

Fs = 200000; %采样频率决定了两个正弦波点之间的间隔 
N = 4096; %采样点数
N1 = 0 : 1/Fs : (N-1)/Fs;
in =sin(6000*2*pi*N1) + sin(14000*2*pi*N1); 
fidc= fopen('C:/Users/Lenovo/Desktop/ccfir/matl/sin_data.txt','wt'); //保存到自己想要的位置上
for x = 1 : N
    fprintf(fidc,'%x\n',round((s(x)+2.12)*58));
end  
fclose(fidc); 

下面用matlab自带的fdatool工具设计FIR数字滤波器,在命令行窗口输入fdatool按下回车就会出现设计窗口。具体过程不再赘述。

下面进行vivado界面的仿真:(比较简单,没有使用IP核,顺便学习一下FIR数字滤波器的经典结构)

 下面开始设计FIR数字滤波器:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: thirsty of cola
// 
// Create Date: 2022/05/20 15:16:11
// Design Name: 
// Module Name: fir
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


`timescale 1ms / 1ps
module fir(
input[7:0] FIR_IN, //滤波器的输入信号
input CLK,         //时钟信号
input RSTn,        //复位信号
output reg[15:0] FIR_OUT//滤波器输出信号
    );    
reg[7:0] delay_pipeline1 ;//延时模块
reg[7:0] delay_pipeline2 ;
reg[7:0] delay_pipeline3 ;
reg[7:0] delay_pipeline4 ;
reg[7:0] delay_pipeline5 ;
reg[7:0] delay_pipeline6 ;
reg[7:0] delay_pipeline7 ;
reg[7:0] delay_pipeline8 ;
reg[7:0] delay_pipeline9 ;
/*第一级流水,将输入信号进行延时,每到来一个时钟信号,
便将输入信号保存到delay_pipelin1中,然后将剩下的依次移动一位。*/
always@(posedge CLK or negedge RSTn)
      if(!RSTn)
               begin
                    delay_pipeline1 <= 8'b0 ;
                    delay_pipeline2 <= 8'b0 ;
                    delay_pipeline3 <= 8'b0 ;
                    delay_pipeline4 <= 8'b0 ;
                    delay_pipeline5 <= 8'b0 ;
                    delay_pipeline6 <= 8'b0 ;
                    delay_pipeline7 <= 8'b0 ;
                    delay_pipeline8<= 8'b0 ;
                    delay_pipeline9<= 8'b0 ;
               end
       else begin
                    delay_pipeline1 <= FIR_IN     ;
                    delay_pipeline2 <= delay_pipeline1 ;
                    delay_pipeline3 <= delay_pipeline2 ;
                    delay_pipeline4 <= delay_pipeline3 ;
                    delay_pipeline5 <= delay_pipeline4 ;
                    delay_pipeline6 <= delay_pipeline5 ;
                    delay_pipeline7 <= delay_pipeline6 ;
                    delay_pipeline8 <=delay_pipeline7 ;
                    delay_pipeline9<= delay_pipeline8 ;
               end
//滤波器系数
wire[7:0] coeff1 = 8'd7;  //在matlab中生成的滤波器系数,也可以是16进制
wire[7:0] coeff2 = 8'd5;
wire[7:0] coeff3 = 8'd51;
wire[7:0] coeff4 = 8'd135;
wire[7:0] coeff5 = 8'd179;
wire[7:0] coeff6 = 8'd135;
wire[7:0] coeff7 = 8'd51;
wire[7:0] coeff8 = 8'd5;
wire[7:0] coeff9 = 8'd7;
//乘积结果保存寄存器
reg signed [16:0] multi_data1 ;
reg signed [16:0] multi_data2 ;
reg signed [16:0] multi_data3 ;
reg signed [16:0] multi_data4 ;
reg signed [16:0] multi_data5 ;
reg signed [16:0] multi_data6 ;
reg signed [16:0] multi_data7 ;
reg signed [16:0] multi_data8 ;
reg signed [16:0] multi_data9 ;
 
//x(n) * h(n-k)
always@(posedge CLK or negedge RSTn) 
      if(!RSTn) 
      begin                                 
          multi_data1 <= 17'b0 ;
      end
       else begin
          multi_data1 <= delay_pipeline1*coeff1 ;    
          end          
//x(1) * h(1)
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data2 <= 16'b0 ;
       else
          multi_data2 <= delay_pipeline2*coeff2 ;
//x(2) * h(2)   
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data3 <= 16'b0 ;
       else
          multi_data3 <= delay_pipeline3*coeff3 ;
  //x(3) * h(3)        
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data4 <= 16'b0 ;
       else
          multi_data4 <= delay_pipeline4*coeff4 ;
//x(4) * h(4)     
 always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data5 <= 16'b0 ;
       else
          multi_data5 <= delay_pipeline5*coeff5 ;
//x(5) * h(5)   
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data6 <= 16'b0 ;
       else
          multi_data6 <= delay_pipeline6*coeff6 ;
//x(6) * h(6)          
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data7 <= 16'b0 ;
       else
          multi_data7 <= delay_pipeline7*coeff7;
//x(7) * h(7)          
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data8 <= 16'b0 ;
       else
          multi_data8 <= delay_pipeline8*coeff8;
//x(8) * h(8)        
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                   
          multi_data9 <= 16'b0 ;
       else
          multi_data9 <= delay_pipeline9*coeff9 ;
//将乘积累加,累加的结果就是滤波后的信号                                                       
always@(posedge CLK or negedge RSTn)
      if(!RSTn)                                  
          FIR_OUT <= 16'b0 ;
       else
          FIR_OUT <= multi_data1 + multi_data2 + multi_data3 + 
          multi_data4 +multi_data5 + multi_data6 + multi_data7 +
           multi_data8 + multi_data9 ;
endmodule

下面开始写testbench:
 

`timescale 1ns / 1ps
//
// Company: 
// Engineer: thirsty of cola
// 
// Create Date: 2022/05/20 14:48:35
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb(
);
reg CLK;
reg [7:0] FIR_IN;
reg RSTn;
reg [7:0] mem[1:4096];   //设计一个rom放读入的数据                                       
wire [15:0] FIR_OUT;
reg [12:0] i;
 //例化FIR滤波器
fir i1 (
       .CLK(CLK),
       .FIR_IN(FIR_IN),
       .FIR_OUT(FIR_OUT),
       .RSTn(RSTn)
);
initial                                               
       begin 
                     $readmemh("C:/Users/Lenovo/Desktop/cc/viva/project_1/sin_data.txt",mem);//将待滤波信号读入mem
                     RSTn= 0;
                     CLK= 0;
                     #50;RSTn= 1;
                     #50000;
                     $stop;
       end  
       
initial
       forever
          #50 CLK = ~CLK;//时钟生成,注意与采样率一致
 
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)                                
          FIR_IN <= 8'b0 ;
       else
          FIR_IN <= mem[i];     //读入数据
 
always@(posedge CLK or negedge RSTn) 
      if(!RSTn)
         i <= 12'd0;
       else
         i <= i + 1'd1;
endmodule

上面我们就完成了一个简单的数字滤波器的设计,其RTL视图如下所示:

 

从上图我们可以看出,FIR数字滤波器的结构比较简单,大体上来说就是一堆延迟器和一堆乘法器还有一堆加法器所组成的,原理也比较好理解。

大家可以参考FIR数字滤波器的直接型结构,方便理解

下面我们来刻苦仿真波形,怎么样吧:

 

 在该例子中,i相当于地址信号,不停的做累加,用于让MEM读取matlab量化后的数据信息。我们可以看到MEM所读取的数据和TXT文本文档中的数据一样,说明我们已近将待处理信号读到了。

下面我们具体分析FIR_IN和FIR_OUT信号,注意要对其中的进制和输出波i选哪个类型进行改变:

 从上图我们可以看出,输入信号和输出信号有很大的差异,滤波器滤除了高频分量而保留下了低频部分的信息,说明设计成功。

注:该例子仅供学习参考,现在的数字滤波器基本都是自适应的,还有待大佬们的指正,谢谢啦。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值