基于FPGA 的FIR IP使用提高一

在上一篇文章《基于Vivado的DDS和FIR核的使用》中,介绍了FIR IP核的使用,当时是通过单个系数集,单个通道实现的滤波功能。

在实际的过程中,可能存在想要动态改变滤波器,实现不同的滤波效果的目的。实现该目的,通常的一种做法为调整滤波器的系数,相应地一般有2种方法,一是通过Reload系数的方式;一是重配置系数的方式。前者是重新装载一份新的系数文件,而后者则是通过事先将所有的系数写入一份系数文件,通过配置来选择使用那一组系数。相比而言,前者配置相对复杂,但是节省资源;而后者配置简单,但是占用更多资源。因此对于仅仅只是少数几种参数进行切换,可以采用后者的方式。

这里就介绍如何通过重配置系数的方式来实现不同的滤波效果,将一个含有多个频率成分的信号,经由不同的带通滤波,得到不同频率的信号,不在通带范围内的信号都被滤掉了。

一、信号产生

通过DDS和加法电路来产生含有不同频率成分的信号。

1、DDS配置

通过DDS IP核,产生4路信号的输出,在配置IP核时,直接将通道设置为4,

因为需要输出4个信号,为了能够区分输出的端口上输出的数据是哪一个通道的,将tuser选项中的 data output设置为chan id,以实现输出通道数据的选择。

待IP配置完成后,进行例化操作,此处不做赘述。前面提到的输出通道选择的相关的代码如下:

reg data_ovalid_r;

reg [15:0] sine_data_25K;   //25K波形数据

reg [15:0] sine_data_45K;   //

reg [15:0] sine_data_65K;  //

reg [15:0] sine_data_85K;  //85K波形数据

always@(posedge clk_i or negedge rst_n)begin

    if(rst_n == 1'b0) begin

        data_ovalid_r <= 1'b0;

        sine_data_25K <= 16'd0;

        sine_data_45K <= 16'd0;

        sine_data_65K <= 16'd0;

        sine_data_85K <= 16'd0;

    end

    else begin

        if(dds_data_valid) begin

            data_ovalid_r <= 1'b1;

            case(dds_data_tuser)   //此处实现输出通道数据的选择

                2'b00:sine_data_25K  <= dds_dataout;

                2'b01:sine_data_45K  <= dds_dataout;

                2'b10:sine_data_65K  <= dds_dataout;

                2'b11:sine_data_85K  <= dds_dataout;

            endcase

        end

        else begin

            data_ovalid_r <= 1'b0;

            sine_data_25K <= 16'd0;

            sine_data_45K <= 16'd0;

            sine_data_65K <= 16'd0;

            sine_data_85K <= 16'd0;

        end           

    end

end

2、混频,求和

求和直接用一个加法电路实现。将上述输出的4路信号进行求和,得到一个含有4个频率成分的信号。

reg signed [17:0] addr_wave;

always@(posedge clk_i or negedge rst_n)begin

    if(!rst_n)

        addr_wave <= 18'd0;

    else if(dds_data_ovalid)

        addr_wave <= sine_data_25K + sine_data_45K + sine_data_65K + sine_data_85K;

    else

        addr_wave <= addr_wave;

end

相应波形的matlab仿真结果如下:

二、FIR设计及IP配置

1、FIR 设计

同样的,FIR的系数设计用matlab实现,此处参考了CSDN 上其他网友的文章,采用了类似的设计。分别得到4个不同的系数coe文件,之后将其合并到一个coe文件中。

设计的带通滤波器的效果如下图所示:

2、FIR IP配置

FIR IP的配置与之前文章中提及的没有太多的区别,差异主要体现在系数文件和系数集个数的不同。

另外,需要留意的是,因系数集个数大于1,会在端口上多出来config配置端口,如下

接下来,重要的是,根据器件的时序要求进行设计,主要关注的是tvalid、tready、tdata等信号,在本例中,将dds输出的valid信号直接给到s_a端口,用作数据的有效信号,结合s_a_tready和s_a_tdata信号实现数据的输入;而对于config端口,通过定时计数的方式,定时一段时间,给一个信号,持续一个时钟周期的高电平,该信号用作cfg_tvalid使用,另外需要配合cfg_tdata。

相关的代码如下:

//计数

always@(posedge clk_50m or negedge clk_locked)begin
    if(!clk_locked)
        cnt <= 16'd0;
    else if(cnt == CNT_MAX)
        cnt <= 16'd0;
    else
        cnt <= cnt + 1'b1;
end

reg  [ 7:0] s_cfg_data;
always@(posedge clk_50m or negedge clk_locked)begin
    if(!clk_locked)
        s_cfg_data <= 8'd0;
    else begin
        if(cnt == CNT_MAX) begin
            sa_cfg_tvalid <= 1'b1;
            if(s_cfg_data == 8'd3)
                s_cfg_data <= 8'd0;
            else
                s_cfg_data <= s_cfg_data + 1'b1;
        end
        else begin
            sa_cfg_tvalid <= 1'b0;
            s_cfg_data <= s_cfg_data;
        end
    end
end
assign sa_cfg_tdata = s_cfg_data;

三、仿真分析

test代码十分简单,这里只贴出了仿真的结果。

结果图中,sa_data_tdata的波形跟matlab给出的波形一致,是4个信号的混频;

而fir_data_out的波形可以看出,在sa_cfg_tdata的不同数值下,实现了不同频率信号的输出,达到了通带内信号通过,带外信号衰减的选频的目的。

至此,整个的工程结束。

四、最后

感谢一下《FIR 高级应用 - 多通道实验》的作者,给了我很多的启发,他的专栏里面的相关内容很值得一看。

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值