特权同学

基于FPGA的多速率信号处理之整数倍抽取篇

0
阅读(5591)

概述:

对于高速无线通信系统,随着采样速率的提高而带来的另外一个问题就是采样后的数据流的速率很高,导致后续的信号处理速度跟不上,特别是对有些同步解调算法,其计算量大,如果数据吞吐率太高是很难满足实时性要求的,所以很有必要对A/D转换后的数据流进行降速处理。

例如,一个实际的无线电通信信号带宽一般为几十千赫兹到几百千赫兹,实际对单信号采样时所需的采样速率是不高的,所以对这种窄带信号的采样数据流进行降速处理或者叫二次采样是完全可能的。多速率信号处理技术为这种降速处理的实现提供了理论依据,其中最为重要也是最为基本的理论是抽取和内插。

 

整数倍抽取:

多速率信号处理中的抽取理论是软件无线电接收机的理论基础。

   所谓整数倍抽取是指把原始采样序列每隔(D-1)个数据取一个,以形成一个新序列,其中D为抽取倍数。

    需要注意的是为了防止抽取后的频谱发生混叠,在抽取前需要先用一个数字滤波器对原信号进行滤波。经过抽取大大提高了信号的频域分辩率。

 

整数倍内插:

多速率信号处理中的内插理论是软件无线电发射机的理论基础。

所谓整数倍内插就是指在两个原始抽样点之间插入(L-1)个零值,而只有将内插零点后的频谱,进行低通滤波才能将插入的零值点变为准确内插值,经过内插将大大提高信号的时域分辩率。

 

具有上变频作用的内插器:

利用内插(插入零点)不仅可以提高时域分辨率,而且也可以用来提高输出信号的频率。

内插后我们得到的信号频谱其实是原始基带谱的各次倍频分量的叠加,所以内插后再加一个带通滤波器即可取出原始基带谱的某一倍频分量。

显然这时的内插器实际上起到了上变频作用,使输出频率最大可以提高(L-1)倍,而其信号的频谱结构不变。

 

取样率的分数倍变换:

之前我们讨论的整数倍抽取和内插实际上是取样率变换的一种特殊情况即整数倍变换的情况,然而在实际中往往会碰到非整数倍即分数倍变换的情况。

那么分数倍变换的情况怎么来实现呢?

假设分数倍变换的变换比为:

                        R = D/L

那么取样率的分数倍变换可以通过先进行L倍内插再进行D倍抽取来实现。

需要注意的是必须内插在前,抽取在后,以确保其中间序列的基带谱宽度不小于原始输入序列谱或输出序列谱的基带频谱宽度,否则将会引起信号失真。

 

 

以上把采样率变换的原理都都做了一个简要的介绍,详细的原理可以参考机械工业出版社的《软件无线电原理与工程应用》一书。

如题,本文的重点是第一部分内容的实验,即整数倍抽取。常理来说,光看时域的波形,似乎这个所谓的低通滤波是多余的,但是我们必须同时考虑到频域的情况。试想一下,如果不做低通滤波直接进行2倍的抽取(前提是假设我们原先对这个基带信号的采样正好满足奈奎斯特采样定理,就是说频域上的波形正好不会重叠的边界情况),那么得到的频域波形是不是就会发生混叠了呢,这是显然的。所以,如果先把待抽取的信号经过低通滤波后再进行抽取就不存在混叠的情况。

 

仿真的波形如下:

 

       由波形图可以看出,sendcode是基带波形,经过低通滤波后的波形为dout,2倍抽取后的信号波形则为dout_2。

 

附上Verilog源码:

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date:    12:50:21 06/04/08

// Design Name:   

// Module Name:    top

// Project Name:  

// Target Device: 

// Tool versions: 

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////////////

module top(clk_500,rst,sendcode,dout,firrdy,dout_2,cqrdy);

 

       input clk_500;                   //主时钟信号,500KHz

       input rst;                            //系统复位信号

      

       output[15:0] sendcode;

       output[33:0] dout;

       output firrdy;

       output[15:0] dout_2;

       output cqrdy;

 

       wire clk_50;               //50KHz时钟信号

       wire clk_250;                    //250KHz时钟信号

       wire[15:0] sendcode;//基带码元

       wire nd;                             //滤波模块使能信号

       wire rfd;                            //滤波模块空闲信号

       wire[33:0] dout;         //低通滤波输出信号

       wire firrdy;                 //滤波完成标志信号

       wire[15:0] dout_2;     //2倍抽取后输出信号

       wire cqrdy;                        //抽取完成标志信号

 

 

       clkdiv            clkdiv(    .clk_500(clk_500),

                                                        .rst(rst),

                                                        .clk_50(clk_50),

                                                        .clk_250(clk_250));    //主时钟的分频模块

 

       source          source(        .clk_50(clk_50),

                                                        .rst(rst),

                                                        .rfd(rfd),

                                                        .sendcode(sendcode),

                                                        .nd(nd));                            //基带码元发送模块

 

       firlow            firlow(  .ND(nd),

                                                        .RDY(firrdy),

                                                        .CLK(clk_500),

                                                        .RFD(rfd),

                                                        .DIN(sendcode),

                                                        .DOUT(dout));                   //16阶FIR低通滤波模块

 

       frechuoqu     frechuoqu(   .clk_250(clk_250),

                                                               .rst(rst),

                                                               .firrdy(firrdy),

                                                               .dout(dout),

                                                               .dout_2(dout_2),

                                                               .rdy(cqrdy));        //2倍抽取模块

 

Endmodule

 

 

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date:    12:58:51 06/04/08

// Design Name:   

// Module Name:    clkfen

// Project Name:  

// Target Device: 

// Tool versions: 

// Description:       主时钟的分频模块

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////////////

module clkdiv(clk_500,rst,clk_50,clk_250);

 

       input clk_500;            //500KHz

       input rst;

       output clk_50;            //50KHz

       output clk_250;   //250KHz

 

       reg clk_50;

       reg clk_250;

       reg[3:0] num;

 

       always @ (posedge clk_500 or posedge rst) begin

              if(rst) begin

                     num <= 0;    

                     clk_250 <= 0;

                     clk_50 <= 0;

                     end

              else begin

                     num <= num+1;

                     case(num)

                            0:    clk_250 <= ~clk_250;

                            1:    clk_250 <= ~clk_250;

                            2:    clk_250 <= ~clk_250;

                            3:    clk_250 <= ~clk_250;

                            4: begin

                                   clk_250 <= ~clk_250;

                                   clk_50 <= ~clk_50;

                                   num <= 0; end

       //                  clk_50 <= ~clk_50;

       //                  num <= 0;

                            default:;

                            endcase

                     end

       end

 

endmodule

 

 

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date:    14:29:06 06/04/08

// Design Name:   

// Module Name:    frechuoqu

// Project Name:  

// Target Device: 

// Tool versions: 

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////////////

module frechuoqu(clk_250,rst,firrdy,dout,dout_2,rdy);

 

       input clk_250;

       input      rst;

       input      firrdy;

       input[33:0] dout;

       output[15:0] dout_2;

       output rdy;

 

       reg[33:0] dout_2;

       reg rdy;

 

       always @ (posedge clk_250 or posedge rst) begin

              if(rst) begin

                     rdy <= 0;

                     dout_2 <= 0;

                     end

              else if(firrdy) begin

                     dout_2 <=dout[33:18];

                     rdy <= 1;

                     end

              else begin

                     rdy <= 0;

                     dout_2 <= 0;

                     end

       end

 

endmodule

 

 

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////

// Company:

// Engineer:

//

// Create Date:    12:51:07 06/04/08

// Design Name:   

// Module Name:    source

// Project Name:  

// Target Device: 

// Tool versions: 

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

////////////////////////////////////////////////////////////////////////////////

module source(clk_50,rst,rfd,sendcode,nd);

 

       input clk_50;              //50KHz时钟信号

       input rst;                     //复位信号,高电平有效

       input rfd;

       output[15:0] sendcode;                   //1bit基带信号,用16bit表示

       output nd;

 

       reg[15:0] sendcode;

       reg[15:0] scode;

       reg[3:0] num;

       reg nd;

 

       always @ (posedge clk_50 or posedge rst) begin

              if(rst) begin

                     nd <= 0;

                     sendcode <= 16'd0;

                     num <= 4'b1111;

                     scode <= 16'b1011101001010101;

                     end

              else if(rfd) begin

                     if(scode[num]) begin

                            sendcode <= 16'h7fff;

                            end

                     else begin

                            sendcode <= 16'h8000;

                            end

                     nd <= 1;

                     num <= num-1;

                     end

              else nd <= 0;

       end

 

endmodule

 

说明:firlow模块是由ISE自带IP Core生成的低通滤波模块,16阶低通滤波器系数是基于systemview生成的。