您身边的网站建设专家
成功案例

【建站服务】三亚公众号代运营公司-域名申请

日期: 2022-09-21 03:29:39 浏览数:15


上往建站提供服务器空间服务商百度快照排名网站托管百度推广运营,致力于设计外包服务与源代码定制开发360推广搜狗推广,增加网站的能见度及访问量提升网络营销的效果,主营:网站公司,百度推广公司电话,官网搭建服务,网站服务企业排名,服务器空间,英文域名等业务,专业团队服务,效果好。



三亚公众号代运营公司


网站建设.png

串行 FIR 滤波器设计

设计说明

设计参数不变,与并行 FIR 滤波器参数一致。即,输入频率为 7.5 MHz 和 250 KHz 的正弦波混合信号,经过 FIR 滤波器后,高频信号 7.5MHz 被滤除,只保留 250KMHz 的信号。

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

串行设计,就是在 16 个时钟周期内对 16 个延时数据分时依次进行乘法、加法运算,然后在时钟驱动下输出滤波值。考虑到 FIR 滤波器系数的对称性,计算一个滤波输出值的周期可以减少到 8 个。串行设计时每个周期只进行一次乘法运算,所以设计中只需一个乘法器即可。此时数据需要每 8 个时钟周期有效输入一次,但是为了保证输出信号频率的正确性,工作时钟需要为采样频率的 8 倍,即 400MHz。这种方法的优点是资源耗费少,但是工作频率要求高,数据不能持续输出。

串行设计

设计中使用到的乘法器模块代码,可参考之前流水线式设计的乘法器。

为方便快速仿真,也可以直接使用乘号 * 完成乘法运算,设计中加入宏定义 SAFE_DESIGN 来选择使用哪种乘法器。

FIR 滤波器系数可由 matlab 生成,具体见附录。

实例

/**********************************************************
>> Description : fir study with serial tech
>> V190403     : Fs:50Mhz, fstop:1-6Mhz, order:16, sys clk:400MHz
***********************************************************/

`define SAFE_DESIGN
 
module fir_serial_low(
    input                rstn,
    input                clk,   // 系统工作时钟,400MHz
    input                en ,   // 输入数据有效信号
    input        [11:0]  xin,   // 输入混合频率的信号数据
    output               valid, // 输出数据有效信号
    output       [28:0]  yout   // 输出数据
    );
 
   //delay of input data enable
    reg [11:0]            en_r ;
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            en_r[11:0]      <= 'b0 ;
        end
        else begin
            en_r[11:0]      <= {en_r[10:0], en} ;
        end
    end
 
    //fir coeficient
    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 ;
 
    //(1) 输入数据移位部分
    reg [2:0]            cnt ;
    integer              i, j ;
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            cnt <= 3'b0 ;
        end
        else if (en || cnt != 0) begin
            cnt <= cnt + 1'b1 ;    //8个周期计数
        end
    end
 
    reg [11:0]           xin_reg[15:0];
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            for (i=0; i<16; i=i+1) begin
                xin_reg[i]  <= 12'b0;
            end
        end
        else if (cnt == 3'd0 && en) begin    //每8个周期读入一次有效数据
            xin_reg[0] <= xin ;
            for (j=0; j<15; j=j+1) begin
                xin_reg[j+1] <= xin_reg[j] ; // 数据移位
            end
        end
    end
 
    //(2) 系数对称,16个移位寄存器数据进行首位相加
    reg  [11:0]          add_a, add_b ;
    reg  [11:0]          coe_s ;
    wire [12:0]          add_s ;
    wire [2:0]           xin_index = cnt>=1 ? cnt-1 : 3'd7 ;
    always @(posedge clk or negedge rstn) begin
        if (!rstn) begin
            add_a  <= 13'b0 ;
            add_b  <= 13'b0 ;
            coe_s  <= 12'b0 ;
        end
        else if (en_r[xin_index]) begin /


(2) 系数对称,16个移位寄存器数据进行首位相加

    reg  [11:0]          add_a, add_b ;

    reg  [11:0]          coe_s ;

    wire [12:0]          add_s ;

    wire [2:0]           xin_index = cnt>=1 ? cnt-1 : 3'd7 ;

    always @(posedge clk or negedge rstn) begin

        if (!rstn) begin

            add_a  <= 13'b0 ;

            add_b  <= 13'b0 ;

            coe_s  <= 12'b0 ;

        end

        else if (en_r[xin_index]) begin //from en_r[1]

            add_a  <= xin_reg[xin_index] ;

            add_b  <= xin_reg[15-xin_index] ;

            coe_s  <= coe[xin_index] ;

        end

    end

    assign add_s = {add_a} + {add_b} ;  

 

    //(3) 乘法运算,只用一个乘法

    reg        [24:0]    mout ;

`ifdef SAFE_DESIGN

    wire                 en_mult ;

    wire [3:0]           index_mult = cnt>=2 ? cnt-1 : 4'd7 + cnt[0] ;

    mult_man #(13, 12)   u_mult_single    //例化自己设计的流水线乘法器

        (.clk        (clk),

         .rstn       (rstn),

         .data_rdy   (en_r[index_mult]),  //注意数据时序对应

         .mult1      (add_s),

         .mult2      (coe_s),

         .res_rdy    (en_mult),  

         .res        (mout)

        );

 

`else

    always @(posedge clk or negedge rstn) begin

        if (!rstn) begin

            mout   <= 25'b0 ;

        end

        else if (|en_r[8:1]) begin

            mout   <= coe_s * add_s ;  //直接乘

        end

    end

    wire                 en_mult = en_r[2];

`endif

 

    //(4) 积分累加,8组25bit数据 -> 1组 29bit 数据

    reg        [28:0]    sum ;

    reg                  valid_r ;

    //mult output en counter

    reg [4:0]            cnt_acc_r ;

    always @(posedge clk or negedge rstn) begin

        if (!rstn) begin

            cnt_acc_r <= 'b0 ;

        end

        else if (cnt_acc_r == 5'd7) begin  //计时8个周期

            cnt_acc_r <= 'b0 ;

        end

        else if (en_mult || cnt_acc_r != 0) begin //只要en有效,计时不停

            cnt_acc_r <= cnt_acc_r + 1'b1 ;

        end

    end

 

    always @(posedge clk or negedge rstn) begin

        if (!rstn) begin

            sum      <= 29'd0 ;

            valid_r  <= 1'b0 ;

        end

        else if (cnt_acc_r == 5'd7) begin //在第8个累加周期输出滤波值

            sum      <= sum + mout;

            valid_r  <= 1'b1 ;

        end

        else if (en_mult && cnt_acc_r == 0) begin //初始化

            sum      <= mout ;

            valid_r  <= 1'b0 ;

        end

        else if (cnt_acc_r != 0) begin //acculating between cycles

            sum      <= sum + mout ;

            valid_r  <= 1'b0 ;

        end

    end

 

    //时钟锁存有效的输出数据,为了让输出信号不是那么频繁的变化

    reg [28:0]           yout_r ;

    always @(posedge clk or negedge rstn) begin

        if (!rstn) begin

            yout_r <= 'b0 ;

        end

        else if (valid_r) begin

            yout_r <= sum ;

        end

    end

    assign yout = yout_r ;

 

    //(5) 输出数据有效延迟,即滤波数据丢掉前15个滤波值

    reg [4:0]    cnt_valid ;

    always @(posedge clk or negedge rstn) begin

        if (!rstn) begin

            cnt_valid      <= 'b0 ;

        end

        else if (valid_r && cnt_valid != 5'd16) begin

            cnt_valid      <= cnt_valid + 1'b1 ;

        end

    end

    assign valid = (cnt_valid == 5'd16) & valid_r ;


endmodule

testbench


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

三亚公众号代运营公司


上往建站提供搭建网站域名注册官网备案服务网店详情页设计企业网店专业网络店铺管理运营全托管公司咨询电话,服务器空间,微信公众号托管网页美工排版,致力于域名申请竞价托管软文推广全网营销,提供标准级专业技术保障,了却后顾之忧,主营:虚拟主机网站推广百度竞价托管网站建设上网建站推广服务网络公司有哪些等业务,专业团队服务,效果好。

服务热线:400-111-6878 手机微信同号:18118153152(各城市商务人员可上门服务)


全国咨询热线:400-111-6878

地址:全国各地都有驻点商务

Copyright © 2021 通陆科技

网站建设上往建站