芯路恒电子技术论坛

 找回密码
 立即注册
热搜: 活动
查看: 101|回复: 0

并行结构FIR滤波器设计

[复制链接]
  • TA的每日心情
    萌哒
    昨天 07:48
  • 3

    主题

    3

    帖子

    56

    积分

    初级会员

    Rank: 3Rank: 3

    积分
    56
    发表于 2019-9-3 12:09:04 | 显示全部楼层 |阅读模式
    本帖最后由 cyy13623649348 于 2019-9-3 12:12 编辑

    1.FIR滤波器的原理与MATLAB设计   
        可以参考之前的串行FIR设计串行结构FIR滤波器设计
    串行结构FIR滤波器设计
    http://www.corecourse.cn/forum.php?mod=viewthread&tid=28287
    (出处: 芯路恒电子技术论坛)

    2.并行FIR滤波器设计与仿真验证
    (1)原理框图设计
        根据FIR直接型结构,滤波器是一个乘累加运算,乘累加的次数由滤波器的阶数决定。可以先设计出并行FIR的框图。
    并行框图.jpg
    1 并行FIR滤波器原理图
    (2)程序设计
        FIR滤波器接口设计:
    1. module Fir_filter(
    2.         rst_n,
    3.         clk,
    4.         Signal_in,
    5.         Signal_out
    6. );
    7.         input rst_n;
    8.         input clk;                                                                //采样时钟
    9.         input [11:0]Signal_in;                                //采样数据输入
    10.         output [28:0]Signal_out;                        //滤波输出
    11.                
    12.         wire signed [11:0]Signed_in;                //输入数据转换成有符号数
    13.         assign Signed_in = Signal_in;
    复制代码
       将输入的数据缓存并对应相加:
    1. /*----------------移位寄存器,用来存储采样数据----------------*/        
    2.         reg signed [11:0]In_reg[15:0];
    3.         reg [3:0]i,j;
    4.         always@(posedge clk or negedge rst_n)
    5.         if(!rst_n)begin
    6.                 for(i=4'd0;i<15;i=i+1'b1)
    7.                         In_reg[i] = 12'd0;
    8.         end
    9.         else begin
    10.                 for(j=4'd0;j<15;j=j+1'b1)
    11.                         In_reg[j+1] <= In_reg[j];
    12.                 In_reg[0] <= Signed_in;
    13.         end

    14. /*----------------将对称系数的输入数据相加----------------*/
    15.         reg signed [12:0]Add_reg[7:0];        //为避免溢出,将两数相加的和扩展一位
    16. //        reg [3:0]k,l;
    17.         always@(posedge clk or negedge rst_n)
    18.         if(!rst_n)begin
    19.                 for(i=4'd0;i<8;i=i+1'b1)
    20.                         Add_reg[i] = 13'd0;
    21.         end
    22.         else begin
    23.                 for(i=4'd0;i<8;i=i+1'b1)
    24.                         Add_reg[i] = {In_reg[i][11],In_reg[i]} + {In_reg[15-i][11],In_reg[15-i]};
    25.                                                                                                 //要扩展一位符号位,使三个数长度相同,但其值不变
    26.         end
    复制代码
       调用IP核进行乘法运算,并行执行需要8个乘法器:
    1. /*----------------例化有符号数乘法器----------------*/
    2.         wire signed [24:0]Mout[7:0];  
    3.         mult mult0 (
    4.                 .clock (clk),
    5.                 .dataa (coe0),
    6.                 .datab (Add_reg[0]),
    7.                 .result (Mout[0])
    8.         );
    复制代码
       最后将乘法器的输出相加:
    1. /*----------------将乘法结果累加----------------*/
    2.         reg signed [28:0]sum;
    3.         reg signed [28:0]yout;
    4.         reg [3:0]m;
    5.         always@(posedge clk or negedge rst_n)
    6.         if(!rst_n)begin
    7.                 sum = 29'd0;
    8.                 yout <= 29'd0;
    9.         end
    10.         else begin
    11.                 yout <= sum;
    12.                 sum = 29'd0;
    13.                 for(m=4'd0;m<8;m=m+1'b1)
    14.                         sum = sum + Mout[m];
    15.         end
    复制代码
    (3)仿真验证
        在串行FIR设计时通过加入混频来验证滤波正确性。也可以直接例化两个DDS,将其结果相加输入滤波器。这里我通过在仿真文件中读取TXT的方式来仿真。
        首先使用MATLAB产生波形,并存入TXT文件。MATLAB代码参考下面。
    使用MATLAB将波形数据存入TXT
    http://www.corecourse.cn/forum.php?mod=viewthread&tid=28290
    (出处: 芯路恒电子技术论坛)

        在仿真文件中读取TXT文件中的数据,文件必须放置在"工程目录\simulation\modelsim"路径下。
    1. //从外部TXT文件(SinIn.txt)读入数据作为测试激励
    2.         integer Pattern;
    3.         reg [11:0] stimulus[200:0];
    4.         initial
    5.         begin
    6.                 //文件必须放置在"工程目录\simulation\modelsim"路径下
    7.                 $readmemb("E4_7_Bin_s.txt",stimulus);//读取原始波形数据读到stimulus中
    8.                 Pattern = 0;
    9.                 repeat(200)begin
    10.                         Pattern = Pattern + 1;
    11.                         Signal_in = stimulus[Pattern];
    12.                         #(`Clk_Period*1);
    13.                 end
    14.         end
    复制代码
        然后将仿真数据写入另一个TXT文件,便于MATLAB对其数据进行分析。
    1. //将仿真数据dout写入外部TXT文件中(out.txt)
    2. integer file_out;
    3. initial
    4. begin
    5.    //文件放置在"工程目录\simulation\modelsim"路径下
    6.         file_out = $fopen("E4_7_Sout.txt");
    7.         if(!file_out)
    8.                 begin
    9.                         $display("could not open file!");
    10.                         $finish;
    11.                 end
    12. end
    13. wire clk_write;
    14. wire signed [28:0] dout_s;
    15. assign dout_s = Signal_out;                //将dout转换成有符号数据
    16. assign clk_write = clk & rst_n;//产生写入时钟信号,复位状态时不写入数据
    17. always @(posedge clk_write)
    18.         $fdisplay(file_out,"%d",dout_s);
    复制代码
        下面是仿真结果:
    仿真.jpg
    图2 滤波器modelsim仿真结果
        最后使用MATLAB读取滤波器输出的数据,得到频谱。MATLAB程序在附件。
    MATLAB2.jpg
    图3 使用MATLAB绘制滤波器输出的频谱

    2019_8_29.zip

    6.45 MB, 下载次数: 1

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|手机版|Archiver|芯路恒电子技术论坛  

    GMT+8, 2019-9-18 00:54 , Processed in 0.101547 second(s), 13 queries , File On.

    Powered by Discuz! X3.3

    © 2001-2017 Comsenz Inc. Template By 【未来科技】【 www.wekei.cn 】

    快速回复 返回顶部 返回列表