一路PN码串行捕获设计--基于《通信收发信机的verilog实现与仿真》实例

这篇日子是参考《通信收发机的Verilog实现与仿真》第五章 Verilog在扩频通信中的应用。

网路上有关PN码产生以及捕获资料很多,但是介于本人对其原理的模糊,实在不知道设计时每一步的具体操作如何。所以花点时间学习一下,放在这里,以防忘记。如果以后做移动通信,或许用的到。就这个东西,前前后后断断续续看了一个星期,花了时间,也算学习了东西。

 

譬如《通信收发信机的verilog实现与仿真》中就有PN码的捕获方案,该方案简单介绍了PN码的产生和捕获原理。产生就是普通的M序列的方法,而捕获用的是滑动相关法。为了加快捕获的速度,设计中使用了10路相关信号,如果而10路相关信号每一路都占用单独的逻辑,那么整个系统的逻辑占有量将成倍增长,原因是在滑动相关捕获方案中首先需要相加,然后相乘。eg,一路捕获,输入是8bit,那么加法器就是两输入的8bit,乘法器就是两输入的16bit。十路捕获,资源占有量,不可容忍,共20个8比特两输入加法器,20个16比特两输入乘法器。为了解决这个问题,本书以及众多解决方案给出的方法是共享逻辑(书中说的是流水线,用三路加法器,二路乘法器来实现相关计算以及最后的检测。因为接收到的信号包含同相信号和正交信号,所以实际上一共是6个加法器,四个乘法器。大大减少了资源。十路PN信号使用十个pn_generator例化实现,共享逻辑的核心和按照设计了一个计数器sys_counter,不同的时间对来自不同路的信号做对应的操作。我整理了一下,用verilogHDL语言的形式与自然语言联合表示如下,不求语法正确,只求理解具体操作。

case(sys_counter)

4‘b0000:3、4、5路输入的信号输入到加法器输入端,加法器进行0、1、2路相关运算;

4’b0001:6、7、8路输入的信号输入到加法器,加法器进行3、4、5路相关运算,0、1、2路的相关结果输入到对应的相关结果寄存器;

4‘b0010:9路输入的信号输入到加法器,加法器进行6、7、8路相关运算,3、4、5路的相关结果输入到对应的相关结果寄存器,0、1路相关结果输入到乘法器输入端;

4’b0011:加法器进行9路信号相关、6、7、8路的相关结果输入到对应的相关结果寄存器,0、1路同相、正交信号功率存储;2、3路相关结果输入到乘法器输入端;

4‘b0100:9路的相关结果输入到对应的相关结果寄存器,4、5路相关结果到乘法器输入端,2、3路同相、正交信号功率存储;0、1路正交、同相相加存储;

4’b0101:6、7路相关结果到乘法器输入端,4、5路同相、正交信号功率存储,2、4路正交、同相相加存储,比较0路功率与阈值的大小,得到capture;

4‘b0110:8、9路相关结果输入到乘法器,6、7路同相、正交信号功率存储,4、5路正交、同相相加存储,比较1路功率与阈值的大小,得到capture;

4’b0111:8、9路同相、正交信号功率存储,6、7路正交、同相相加存储,比较2路功率与阈值的大小,得到capture;

4‘b1000:8、9路正交、同相相加存储,比较3路功率与阈值的大小,得到capture;

4’b1001:比较4路功率与阈值的大小,得到capture;

4‘b1010:比较5路功率与阈值的大小,得到capture;

4’b1011:比较6路功率与阈值的大小,得到capture;

4‘b1100:比较7路功率与阈值的大小,得到capture;

4’b1101:比较8路功率与阈值的大小,得到capture;

4‘b1110:比较9路功率与阈值的大小,得到capture;

4’b1111:0、1、2路输入的信号输入到加法器;

endcase

到4‘b1111,完成一个周期,因为每16个clk只需要度每一路完成一次操作,所以共享逻辑可以完成这样的功能,而且分几次寄存了计算的结果。数据的输入速度是clk的1/16。

信号处理过程中分几次寄存数据,输入数据寄存,加法结果寄存(这个是必要的,也就是相关处理的结果寄存),乘法输入寄存(需要提前将进行乘法的数据从相关结果寄存器中读出)、乘法结果寄存、功率结果寄存。

计算步骤:输入信号和加法器上次结果输入到加法器根据PN值相加进行相关操作、求同相正交信号的平方、求一路信号的功率(也就是同相信号平方+正交信号平方)、阈值比较等到捕获同步的结果。这写代码可以见参考书,有一次证明,看代码是件痛苦的事情,这些代码还有很多注释。另外:可能作者最初写代码的时候是整个系统用一个module实现的,而为了排版书籍的缘故将原来的程序划分为几个块,也为了更好的注释,但是划分块以后没有对一些信号进行更好的处理,譬如一些信号在一个块中没有定义却拿来使用,而sys_counter在serial_xiangguan模块中只是定义,没有具体实现,读者只有参考了后面的模块才能知道。还有许多,不一一提及。而这个计数器为什么定义那么多位,而且为什么那样定义,我还不清楚,等做完后续实验再说一下。而且为了节省资源,对resi_*和resq_*进行了共享,先放置相关结果,等相关数据使用完毕后,再放置相关后平方的结果。等等,这些内容在程序中并没有交代清楚。

 

对于上面的实例无法透彻理解的前提下,就觉得做一路捕获试试,或许能够理解基本原理与操作。不考虑系统的效率问题,单路信号,时钟clk2设置为输入数据的4倍就可以,基本操作还是相加实现相关、相乘实现同相或正交功率计算、相加得到信号功率、与阈值比较的到capture结果。pn_generator没有变化。实现捕获的程序如下。

module pn_capture(clk, clr, en, data_i, data_q, a, capture);
    input clk;//4倍于 data的时钟
    input clr;//清除
    input en;//使能
    input [7:0] data_i;//同相信号
    input [7:0] data_q;//正交信号
    output reg capture;//捕获信号
  
  input [6:0] a;//PN码生成器初始值
  reg [1:0] count;//2bit计数器,控制计算过程
  parameter idle=2'b00,co_add=2'b01,mul=2'b10,power_add=2'b11;

                                          //对应不同的计算状态
  parameter criterion=37'h07_ffff_ffff;//峰值阈值
  reg signed [14:0] resi_add;//同相相加结果,也就是相关
  reg signed [14:0] resq_add;//正交相加结果,也就是相关
  reg signed [35:0] mul_result_i;//同相相关后平方
  reg signed [35:0] mul_result_q;//正交相关后平方
  reg [36:0] res;//功率寄存
  wire pn;//PN码

//生成PN码  
pn_generator pn0(.a(a), .clk(clk), .clr(clr), .en(en), .pn(pn));

 

//控制计算的计数器

always @(posedge clk)
begin
    if(clr)    count<=0;
    else    if(en)    
      begin
        if(count==2'b11)    count<=0;
        else    count<=count+1'b1;
    end
    else    count<=0;
end

 

//

always @(posedge clk)
begin
    if(clr)    
      begin 
        resi_add<=0;resq_add<=0;
        mul_result_i<=0;mul_result_q<=0;
        res<=0;
    end
  else    if(en)
        case(count)
       idle:    begin 
                      resi_add<=resi_add;resq_add<=resq_add;//
                 end
       co_add:  begin//相关
                 if(pn)   

                    begin resi_add<=resi_add-data_i;

                             resq_add<=resq_add-data_q;end
                 else    begin resi_add<=resi_add+data_i;

                          resq_add<=resq_add+data_q;end
             end
         mul:     begin //相乘
                    mul_result_i[35:0]<=resi_add*resi_add;
                    mul_result_q[35:0]<=resq_add*resq_add;
                     end
    power_add:    begin res[36:0]<=mul_result_i+mul_result_q;end//功率
    endcase
end

 

//捕获判断

always @(posedge clk)
begin
    if(clr)    capture<=0;
  else    if(en)
      begin
        if(res>criterion)    capture<=1;
        else    capture<=0;
    end
        else    capture<=0;
end
endmodule

 

 

按照作者的意图,按照我的理解,将作者原来的程序修正如下。感受啊!作者不认真,真的要人命,作者一偷懒,读者费死劲,作者一疏忽,读者真是服。

module pn_serial_corelated(clk, clr, data_i, data_q, pn);
    input clk;
    input clr;
    input [7:0] data_i;
    input [7:0] data_q;
    output reg pn;
    reg pn_1;
  reg pn_2;
  reg en;
    reg [6:0] a,a0,a1,a2,a3,a4,a5;
  wire [9:0]pn_10;
  reg signed [7:0] reg_i,reg_q;
  reg signed [14:0] resi_add_0,resi_add_1,resi_add_2;
  reg signed [14:0] resq_add_0,resq_add_1,resq_add_2;
  reg signed [14:0] resi_in_0,resi_in_1,resi_in_2;
  reg signed [14:0] resq_in_0,resq_in_1,resq_in_2;
  reg signed [35:0] resi_0,resi_1,resi_2,resi_3,resi_4;
  reg signed [35:0] resi_5,resi_6,resi_7,resi_8,resi_9;
  reg signed [35:0] resq_0,resq_1,resq_2,resq_3,resq_4;
  reg signed [35:0] resq_5,resq_6,resq_7,resq_8,resq_9;
  reg signed [36:0] res_0,res_1,res_2,res_3,res_4,res_5;
  reg signed [36:0] res_6,res_7,res_8,res_9;
  reg [3:0] waitnum;
  reg [16:0] sys_counter;
  reg [3:0] pn_max_num;
  reg [36:0] criterion;
  reg capture;
  reg signed [36:0] max;
  wire signed [35:0] mul_result_i_0;
  wire signed [35:0] mul_result_q_0;
  wire signed [35:0] mul_result_i_1;
  wire signed [35:0] mul_result_q_1;  
  reg signed [14:0] mul_i_0;
  reg signed [14:0] mul_q_0;
  reg signed [14:0] mul_i_1;
  reg signed [14:0] mul_q_1;
  
  wire en_pn; 
  
  
pn_generator mypn0(.a(a0),.clk(clk),.pn(pn_10[0]),.en(en_pn),.clr(clr));
pn_generator mypn1(.a(a1),.clk(clk),.pn(pn_10[1]),.en(en_pn),.clr(clr));
pn_generator mypn2(.a(a2),.clk(clk),.pn(pn_10[2]),.en(en_pn),.clr(clr));
pn_generator mypn3(.a(a3),.clk(clk),.pn(pn_10[3]),.en(en_pn),.clr(clr));
pn_generator mypn4(.a(a4),.clk(clk),.pn(pn_10[4]),.en(en_pn),.clr(clr));
pn_generator mypn5(.a(a5),.clk(clk),.pn(pn_10[5]),.en(en_pn),.clr(clr));
pn_generator mypn6(.a(a),.clk(clk),.pn(pn_10[6]),.en(en_pn),.clr(clr));
pn_generator mypn7(.a(a),.clk(clk),.pn(pn_10[7]),.en(en_pn),.clr(clr));
pn_generator mypn8(.a(a),.clk(clk),.pn(pn_10[8]),.en(en_pn),.clr(clr));
pn_generator mypn9(.a(a),.clk(clk),.pn(pn_10[9]),.en(en_pn),.clr(clr));

//按照面积优化,会将mypn7/mypn8/mypn9优化。

//wire en_pn;
assign en_pn=((sys_counter==4'b0011)&&en);
always @(posedge clk)
begin
    if(clr)
      begin
        a<=7'b100_0000;a0<=7'b000_1000;
    a1<=7'b000_0001;a2<=7'b100_0001;
    a3<=7'b100_0100;a4<=7'b100_1001;
    a5<=7'b100_1100;
    reg_i<=0;reg_q<=0;   
    end
    else    if(en)
      begin
        if(sys_counter[3:0]==4'b1111)
        begin
          reg_i<=data_i; reg_q<=data_q;
      end
    end
end

always @(posedge clk)
begin
     if(clr)
       begin
      resi_add_0<=0;resi_add_1<=0;resi_add_2<=0;
    resq_add_0<=0;resq_add_1<=0;resq_add_2<=0;
    resi_in_0<=0;resi_in_1<=0;resi_in_2<=0;
    resq_in_0<=0;resq_in_1<=0;resq_in_2<=0;
    resi_0<=0;resi_1<=0;resi_2<=0;resi_3<=0;resi_4<=0;
    resi_5<=0;resi_6<=0;resi_7<=0;resi_8<=0;resi_9<=0;
    resq_0<=0;resq_1<=0;resq_2<=0;resq_3<=0;resq_4<=0;
    resq_5<=0;resq_6<=0;resq_7<=0;resq_8<=0;resq_9<=0;
    res_0<=0;res_1<=0;res_2<=0;res_3<=0;res_4<=0;
    res_5<=0;res_6<=0;res_7<=0;res_8<=0;res_9<=0;
   end
    else    if(en)
      begin
      case(pn)
    1'b0:
        begin
        resi_add_0<=resi_in_0+reg_i;
      resq_add_0<=resq_in_0+reg_q;
    end
    1'b1:
        begin
        resi_add_0<=resi_in_0-reg_i;
      resq_add_0<=resq_in_0-reg_q;
    end
    endcase
      case(pn_1)
    1'b0:
        begin
        resi_add_1<=resi_in_1+reg_i;
      resq_add_1<=resq_in_1+reg_q;
    end
    1'b1:
        begin
        resi_add_1<=resi_in_1-reg_i;
      resq_add_1<=resq_in_1-reg_q;
    end
    endcase    
    case(pn_2)
    1'b0:
        begin
        resi_add_2<=resi_in_2+reg_i;
      resq_add_2<=resq_in_2+reg_q;
    end
    1'b1:
        begin
        resi_add_2<=resi_in_2-reg_i;
      resq_add_2<=resq_in_2-reg_q;
    end
    endcase
    case(sys_counter[3:0])
    4'b0000:
        begin
        pn<=pn_10[3];
      pn_1<=pn_10[4];
      pn_2<=pn_10[5];
      resi_in_0<=resi_3[14:0];
      resi_in_0<=resq_3[14:0];
      resi_in_1<=resi_4[14:0];
      resq_in_1<=resq_4[14:0];
      resi_in_2<=resi_5[14:0];
      resq_in_2<=resq_5[14:0];
    end
        4'b0001:
        begin
        pn<=pn_10[6];
      pn_1<=pn_10[7];
      pn_2<=pn_10[8];
      resi_0[14:0]<=resi_add_0;
      resi_1[14:0]<=resi_add_1;
      resi_2[14:0]<=resi_add_2;
      resi_in_0<=resi_6[14:0];
      resi_in_1<=resi_7[14:0];
      resi_in_2<=resi_8[14:0];
      resq_0[14:0]<=resq_add_0;
      resq_1[14:0]<=resq_add_1;
      resq_2[14:0]<=resq_add_2;
      resq_in_0<=resq_6[14:0];
      resq_in_1<=resq_7[14:0];
      resq_in_2<=resq_8[14:0];
    end
    4'b0010:
        begin
        pn<=pn_10[9];
      resi_3[14:0]<=resi_add_0;
      resi_4[14:0]<=resi_add_1;
      resi_5[14:0]<=resi_add_2;
      resi_in_0<=resi_9[14:0];
      resq_3[14:0]<=resq_add_0;
      resq_4[14:0]<=resq_add_1;
      resq_5[14:0]<=resq_add_2;
      resq_in_0<=resq_9[14:0];
      
      if(sys_counter[10:4]==7'b000_0000)
          begin
            mul_i_0<=resi_0[14:0];
        mul_q_0<=resq_0[14:0];
        mul_i_1<=resi_1[14:0];
        mul_q_1<=resq_1[14:0];
        end
    end
        4'b0011:
        begin
        resi_6[14:0]<=resi_add_0;
      resi_7[14:0]<=resi_add_1;
      resi_8[14:0]<=resi_add_2;
      resq_6[14:0]<=resq_add_0;
      resq_7[14:0]<=resq_add_1;
      resq_8[14:0]<=resq_add_2;
      if(sys_counter[10:4]==7'b000_0000)
          begin
            mul_i_0<=resi_2[14:0];
        mul_q_0<=resq_2[14:0];
        mul_i_1<=resi_3[14:0];
        mul_q_1<=resq_3[14:0];
        resi_0<=mul_result_i_0;
        resq_0<=mul_result_q_0;
        resi_1<=mul_result_i_1;
        resi_1<=mul_result_q_1;
        end
    end
    4'b0100:
        begin
        resi_9[14:0]<=resi_add_0;
      resq_9[14:0]<=resq_add_0;
      if(sys_counter[10:4]==7'b000_0000)
          begin
            mul_i_0<=resi_4[14:0];
        mul_q_0<=resq_4[14:0];
        mul_i_1<=resi_5[14:0];
        mul_q_1<=resq_5[14:0];
        resi_2<=mul_result_i_0;
        resq_2<=mul_result_q_0;
        resi_3<=mul_result_i_1;
        resq_3<=mul_result_q_1;
        res_0<=resi_0+resq_0;
        res_1<=resi_1+resq_1;
        end
      
    end
    4'b0101:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            mul_i_0<=resi_6[14:0];
        mul_q_0<=resq_6[14:0];
        mul_i_1<=resi_7[14:0];
        mul_q_1<=resq_7[14:0];
        resi_4<=mul_result_i_0;
        resq_4<=mul_result_q_0;
        resi_5<=mul_result_i_1;
        resi_5<=mul_result_q_1;
        res_2<=resi_2+resq_2;
        res_3<=resi_3+resq_3;
        if(res_0>max)
            begin
              pn_max_num<=0;
            max<=res_0;
          end
        end
    end
    4'b0110:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
           mul_i_0<=resi_8[14:0];
         mul_q_0<=resq_8[14:0];
         mul_i_1<=resi_9[14:0];
         mul_q_1<=resq_9[14:0];
         resi_6<=mul_result_i_0;
         resq_6<=mul_result_q_1;
         resi_7<=mul_result_i_1;
         resi_7<=mul_result_q_1;
         res_4<=resi_4+resq_4;
         res_5<=resi_5+resq_5;
         if(res_1>max)
             begin
             pn_max_num<=1;
           max<=res_1;
         end
        end
    end
    4'b0111:
        begin
        if(sys_counter[10:4]==7'b000_0000)
                    begin
            resi_8<=mul_result_i_0;
        resq_8<=mul_result_q_0;
        resi_9<=mul_result_i_1;
        resq_9<=mul_result_q_1;
        res_6<=resi_6+resq_6;
        res_7<=resi_7+resq_7;
        if(res_2>max)
            begin
              pn_max_num<=2;
            max<=res_2;
          end
                    end        
    end
    4'b1000:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            res_8<=resi_8+resq_8;
        res_9<=resi_9+resq_9;
        if(res_3>max)
            begin
              pn_max_num<=3;
            max<=res_3;
          end
        end
    end
    4'b1001:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            if(res_4>max)
            begin
              pn_max_num<=4;
            max<=res_4;
          end
        end
    end
    4'b1010:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            if(res_5>max)
            begin
              pn_max_num<=5;
            max<=res_5;
          end
        end        
    end
    4'b1011:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            if(res_6>max)
            begin
              pn_max_num<=6;
            max<=res_6;
          end
        end         
    end
    4'b1100:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            if(res_7>max)
            begin
              pn_max_num<=7;
            max<=res_7;
          end
        end         
    end
        4'b1101:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            if(res_8>max)
            begin
              pn_max_num<=8;
            max<=res_8;
          end
        end         
    end 
        4'b1110:
        begin
        if(sys_counter[10:4]==7'b000_0000)
          begin
            if(res_9>max)
            begin
              pn_max_num<=9;
            if(res_9>criterion)    capture<=1;
          end
            else
            begin
              if(max>criterion)    capture<=1;
          end
        end         
    end    
    4'b1111:
        begin
        pn<=pn_10[0];
      pn_1<=pn_10[1];
      pn_2<=pn_10[2];
      resi_in_0<=resi_0[14:0];
      resi_in_1<=resi_1[14:0];
      resi_in_2<=resi_2[14:0];
      resq_in_0<=resq_0[14:0];
      resq_in_1<=resq_1[14:0];
      resq_in_2<=resq_2[14:0];
    end
    default:
        begin
    resi_in_0<=resi_in_0;resi_in_1<=resi_in_1;resi_in_2<=resi_in_2;
    resq_in_0<=resq_in_0;resq_in_1<=resq_in_1;resq_in_2<=resq_in_2;
    resi_0<=resi_0;resi_1<=resi_1;resi_2<=resi_2;resi_3<=resi_3;resi_4<=resi_4;
    resi_5<=resi_5;resi_6<=resi_6;resi_7<=resi_7;resi_8<=resi_8;resi_9<=resi_9;
    resq_0<=resq_0;resq_1<=resq_1;resq_2<=resq_2;resq_3<=resq_3;resq_4<=resq_4;
    resq_5<=resq_5;resq_6<=resq_6;resq_7<=resq_7;resq_8<=resq_8;resq_9<=resq_0;
            end    
    endcase
    end
end

always @(posedge clk)
begin
    if(clr)    begin waitnum<=0;en<=1;end
  else    if(~en)
      begin
        waitnum<=waitnum+1'b1;
    if(waitnum==4'b1111)    en<=1;
    end
    else    if(sys_counter[10:0]==11'b000_0000_1111)
      begin
        if(res_9     end
end

always @(posedge clk)
begin
    if(clr)    sys_counter<=0;
  else    if(en)
      begin
        if(sys_counter[10:0]==11'b000_0000_1111)

//testbench里面这个地方是

//sys_counter[10:0]==11'b111_1110_1111;
        begin
          sys_counter[10:0]<=0;
        sys_counter[15:11]<=sys_counter[15:11]+1'b1;
      end
    else    sys_counter<=sys_counter+1'b1;
    end
end

always @(posedge clk)
begin
    if(clr)    criterion<=37'h07_ffff_ffff;
end
MULT18X18 mult1(.P(mul_result_i_0),.A(mul_i_0),.B(mul_i_0));
MULT18X18 mult2(.P(mul_result_q_0),.A(mul_q_0),.B(mul_q_0));
MULT18X18 mult3(.P(mul_result_i_1),.A(mul_i_1),.B(mul_i_1));
MULT18X18 mult4(.P(mul_result_q_1),.A(mul_q_1),.B(mul_q_1));
      
endmodule

作者没有对每个模块的测试平台给出注释,而且就其中用到的数据文本也没给出基本的说明,希望再版的时候能注意一下。

下面是PN码的一些知识,摘抄自《CDMA系统的PN码技术》 武汉理工大学信息工程学院  吴薇

PN:Pseudo-Noise。

 

PN码序列同步是扩频系统特有的,也是扩频技术 中的难点。CDMA系统要求接收机的本地伪随机码与接收到的PN码在结构、频率和相位上完全一致,否则就不能正常接收所发送的信息,接收到的只是一片噪声。若实现了收发同步但不能保持同步,也无法准确可靠地获取所发送的信息 数数据 。因此,PN码序列的同步是CDMA扩频通信的关键 技术 。 

CDMA系统中的PN码同步过程分为PN码捕获(精同步)和PN码跟踪(细同步)两部分。

 

常用的PN码捕获方法有:

1、滑动相关法
接收系统在搜索同步时,它的码序列发生器以与发射机码序列发生器不同的速率工作,致使这两个码序列在相位上互相滑动,只有在达到一致点时,才停下来,因此称之为滑动相关法。

接收信号与本地PN码相乘后积分,求出它们的互相关值,然后与门限检测器的某一门限值比较,判断是否已捕获到有用信号。它利用了PN码序列的相关徨性,当两个相同的码序列相位一致时,其相关值输出最大。一旦确认捕获完成,捕获指示信号的同步脉冲控制搜索控制钟,调整PN码发生器产生的PN码重复频率和相位,使之与收到的信号保持同步。

  由于滑动相关器对两个PN码序列按顺序比较相关,所以该方法又称顺序搜索法。滑动相关器简单,应用簋广,缺点是当两个PN码的时间差或相位差过大时,相对滑动速度簋慢,导致搜索时间过长,特别是对长PN码的捕获时间过长,必须采取措施限定捕获范围,加快捕获时间,改善其性能。

  使滑动相关器实用的有效方法之一是采用特殊码序列,特殊码序列要足够短,以便在合理时间内对所有码位进行搜索。至于短到什么程度,由满足相关性要求限定。这种加前置码的方法称同步引导法。引导码同步要求低、简单易实现,是适合各种应用的同步方法。

  可捕码由若干较短码序列组合而成,其码序列应与各组成码序列保持一定的相关关系。这类码中最著名的是JPL码。

2、序贯估值法
 序贯估值法是另一种减少长码捕获时间的快速捕获方法,它把收到的PN码序列直接输入本地码发生器的移位寄存器,强制改变各级寄存器的起始状态,使其产生的PN码与外来码相位一致,系统即可立即进行同步跟踪状态,缩短了本地PN码与外来PN码相位一致所需的时间。

  该方法先检测收到码信号中的PN码,通过开关,送入n级PN码发生器的移位寄存器。待整个码序列全部进入填满后,在相关器中,将产生的PN码与收到的码信号进行相关运算,在比较器中将所得结果与门限进行比较。若未超过门限,则继续上述过程。若超过门限,则停止搜索,系统转入跟踪状态。理想情况下,捕获时间Ts=nTc,(Tc为PN码片时间宽度)。该方法捕获时间虽短,但存在一些问题,它先要对外来的PN码进行检测,才能送入移位寄存器,要做到这一点有时很困难。另外,此法抗干扰能力很差,因为逐一时片进行估值和判决,并未利用PN码的抗干扰特性。但在无干扰条件下,它仍有良好的快速初始同步性能。

 

3、匹配滤波器法
用于PN同步捕获的匹配滤波器一般采用延时线匹配滤波器,其目的是识别码序列,它能在特殊结构中识别特殊序列,而且只识别该序列。假设一个输入信号是7bit码序列1110010双相调制的信号,每当码有1-0过渡时,反相信号进入延时线,直到第1bit在T7,第2bit在T6。当全部时延元件都填满,而且信号调制码与滤波器时延元件相位一致时,T2的信号相位与T5、T6、T7的相位相同,时延元件T1、T3、T4也具有相同的信号相位。把{T2、T5、T6、T7}与{T1、T3、T4}两组分别相加,把{T1、T3、T4}之和倒相输出,再将这两个结果相加,包含在全部7个元件中的信号能量同相相加,整个输出是未处理的7倍。根据该能量关系可以识别码序列。

  要增强产生的信号,可以靠附加更多的时延元件实现,在这种结构中得到的处理增益为Gp=10lgn(n是参加求和的时延元件数)。

  在要求快速锁定及使用长码的CDMA扩频通信中,宜采用SAW-TDL-MF作同步器。对于待定信号,匹配滤波器具有时间 自动 能力,无需PN码时钟同步与RF载波相位锁定,既避免了 数据 信息比特以外的同步,又完成了扩频信号的相关处理。引导码进入程控编码SAW-TDL-MF后,其输出是噪声基底上的底尖相关峰。在扩频通信中,噪声功率控制接收机的AGC,因而信号功率(即相关峰值)在起伏的噪声环境中变化很大。门限计算器的功能根据包络检测输出,确定动态门限电平,提供给同步检测器,保证在低SNR时有可允许的同步误差。动态门限电平取在主峰高度与最大旁峰之间时,噪声引起的底同步误差最小。当SAW-TDL检波输出包络超过动态门限时,同步检测器为接收机宽带频率合成器提供一个逻辑电平同步信号。

 

××××××××××××××××××××××××××××××××××××××

开始想学习3G,看了一些资料,发现讲协议的太多,根本无法下手,不懂的几乎是整体。然后觉得看移动通信可能好点,果然涉及到具体技术的内容,再仔细才发现扩频通信应该算是现在比较主流的一种技术。

最佳通信系统=最佳发送机+最佳接收机。

一般地,认为:最佳发送就是扩频发送,最佳接受就是相关接受。

 扩频技术是一种信息处理传输技术。扩频技术是利用同域传输数据(信息)无关的码对被传输信号扩展频谱,使之占有远远超过被传送信息所必需的最小带宽。具有较强的抗干扰、抗衰落、抗多径性能以及频谱利用率高、多址通信。

  扩频信号具有以下三个特性:

  1.扩频信号是不可预测的伪随机的宽带信号;

  2.扩频信号带宽远大于欲传输数据(信息)带宽;

  3.接收机中必须有与宽带载波同步的副本。

   传输信息时所用信号带宽远大于传输些信息所需最小带宽的一种信号处理技术。发射端展宽频带是用独立于所传数据的码来实现,接收端用同步的相同码解扩以恢复所传数据。扩频的基本方法有,直接序列(DS)、跳频(FH)、跳时(TH)和线性调频(Chirp)等4种,目前人们所熟知的新一代手机标准CDMA就是直接序列扩频技术的一个应用。而跳频、跳时等技术则主要应用于军事领域,以避免己方通信信号被敌方截获或者干扰。扩频的主要特点为:抗干扰,抗多径衰落,低截获概率,码分多址能力,高距离分辨率和精确定时特性等。

 

 《扩频通信数字基带信号处理算法及其VLSI实现》 张欣 第七章 扩频码序列的捕获

该文献对PN码的理论阐述比较有条理。并且给出了几种捕获的方法和VLSI结构。

你可能感兴趣的:(一路PN码串行捕获设计--基于《通信收发信机的verilog实现与仿真》实例)