当前位置:   article > 正文

自适应均衡器的原理与实现

自适应均衡

前言:在数字通信系统中插入一种参数可调的滤波器,以校正和补偿系统特性,减少码间干扰的影响,这种起补偿作用的滤波器称为均衡器。

目录

一、自适应均衡器的原理

1、LMS算法

2、LMS算法的原理

3、符号LMS算法

二、自适应均衡器实现

1、matlab仿真

2、产生测试数据

3、定点数在FPGA中的运算

4、自适应均衡器的verilog实现

三、仿真测试结果

一、自适应均衡器的原理

在无线通信系统中,由于通信的信道存在多径效应、信道带宽有限及信道特性本身的不完善等因素,导致数据通过信道时将不可避免地产生码间干扰,从而降低系统的性能,影响通信的质量。自适应均衡器是基于自适应均衡技术的装置,能够基于对信道特性的测量随时调整自身的系数,以适应信道特性的变化,消除码间干扰。

在实现自适应均衡器之前需要了解自适应算法。

1、LMS算法

LMS算法(Least Mean Square)根据均方误差准则设计的一种有效算法,它要求均方估计误差达到最小,即

\varepsilon _{n} = E[e_{n}^{2}] = min

式中,e_{n} = y_{dn} - \hat{y}_{dn} = y_{dn} - f(X)

2、LMS算法的原理

LMS算法可以用下面一组公式递推来表示:

                                                ​​​​​​​        ​​​​​​​        y(n) = W^{H}(n)X(n)

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        e(n) = d(n) - y(n)

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​W(n+1) = W(n) + 2uX(n)e^{*}(n)

式中,W(n)为滤波器系数向量,也称权值;X(n)是输入信号组成的一组向量;y(n)是输出信号;d(n)是期望信号;e(n)是误差信号;u是加权向量更新时的步长因子,u越大,算法收敛越快,但同时收敛后的误差信号也越大;u越小,则算法的收敛速度越慢,但同时收敛后的误差信号也相应减小,稳态性能更好。

图1 LMS算法的一般实现结构

如果所有运算均串行执行,则完成一次权值更新需要2N次乘法运算、2N+1次加减法运算和N次移位运算。又因为LMS算法本身是严格的闭环系统,每次权值更新均需要在一个数据周期内完成,因此FPGA的系统时钟频率需要远高于数据速率,这对FPGA的时钟要求很高。

3、符号LMS算法

LMS算法的步骤虽然不能减少,但对滤波器系数更新的运算可以简化。符号LMS算法只给出梯度迭代的方向,而不具体给出数值,即:

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        y(n) = W^{H}(n)X(n)

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        e(n) = d(n) - y(n)

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        W(n+1) = W(n) + uX(n)sign[e^{*}(n)]

在性能上不如LMS算法稳定,且误差相对较大,但运算速度增加、运算量减小并节约了硬件资源。

二、自适应均衡器实现

1、matlab仿真

自适应均衡器的性能仿真主要分为两个方面:相同多径干扰条件下信噪比与系统性能改善情况,以及相同信噪比条件下多径干扰与系统性能改善情况。

Matlab代码如下:

  1. len = 20000;   
  2. Tlen = 2000;   
  3. step = 1/128;  
  4. s = zeros(1,len);  
  5. s1 = zeros(1,len); 
  6. x = zeros(1,N);    
  7. w = ones(1,N);    
  8. s = randsrc(1,len);
  9. s1(2:len) = s(1:len-1);
  10. p = 0.1;
  11. SNR = [0:10];
  12. for db = 1:length(SNR)
  13.     s2 = sqrt(1-p)*s + sqrt(p)*s1;
  14.         s3 = awgn(s2,db,'measured');
  15.     for i=N:len
  16.         x(1:N) = s3(i:-1:i-N+1);   
  17.         y(i) = x*w';              
  18.         e(i) = s(i-3) - y(i);      
  19.         w = w + 2*step*sign(x)*e(i)';
  20.         if y(i)>0
  21.             y1(i) = 1;
  22.         else
  23.             y1(i) = -1;
  24.         end
  25.         if s3(i)>0
  26.             y2(i) = 1;
  27.         else
  28.             y2(i) = -1;
  29.         end
  30.     end
  31.    errornum1 = sum(y1(Tlen:end)~=s(Tlen-3:end-3)); 
  32.    errornum2 = sum(y2(Tlen:end)~=s(Tlen:end));
  33.    ber1(db) = errornum1/(len-Tlen);
  34.    ber2(db) = errornum2/(len-Tlen);
  35. end
  36. subplot(121);
  37. semilogy(SNR,ber1,'+-',SNR,ber2,'-');
  38. xlabel('信噪比(SNR)');ylabel('误码率');title('信噪比与误码率的关系(P=0.1)');
  39. legend('有均衡器','无均衡器');
  40. db=10;
  41. p=[0:0.05:1];
  42. for m=1:length(p)
  43.     s2=sqrt(1-m*0.05)*s+sqrt(m*0.05)*s1;
  44.     s3=awgn(s2,db,'measured');
  45.     for i=N:len
  46.         x(1:N)=s3(i:-1:i-N+1);
  47.         y(i)=x*w';
  48.        e(i)=s(i-3)-y(i);
  49.         w=w+2*step*sign(x)*e(i)';
  50.         if y(i)>0
  51.             y1(i)=1;
  52.         else
  53.             y1(i)=-1;
  54.         end
  55.         if s3(i)>0
  56.             y2(i)=1;
  57.         else
  58.             y2(i)=-1;
  59.         end
  60.     end
  61.     errornum1=sum(y1(Tlen:end)~=s(Tlen-3:end-3));
  62.     errornum2=sum(y2(Tlen:end)~=s(Tlen:end));
  63.     ber3(m)=errornum1/(len-Tlen);
  64.     ber4(m)=errornum2/(len-Tlen);
  65. end
  66. subplot(122);
  67. semilogy(p,ber3,'+-',p,ber4,'-');
  68. xlabel('多径损耗(P)');ylabel('误码率');title('多径损耗因子与误码率的关系 (SNR=10dB)');
  69. legend('有均衡器 ','无均衡器');

2 自适应均衡器对系统性能改善关系图

2、产生测试数据

首先用matlab产生测试数据,将数据保存进txt文件中,利用modelsim仿真读取测试数据,再将仿真结果写入外部文件中,最后再matlab中对比FPGA结果和仿真结果。

Matlab代码如下:

  1. len = 2000;       
  2. step = 1/128;     
  3. N = 7;            
  4. B = 16;     
  5. p = 0.1;           
  6. SNR = 10;         
  7. s = randsrc(1,len);
  8. s1 = zeros(1,len); 
  9. s1(2:len) = s(1:len-1);
  10. s2 = sqrt(1-p)*s + sqrt(p)*s1; 
  11. s3 = awgn(s2,SNR,'measured'); 
  12. maxs3 = max(abs(s3));  
  13. maxs = max(abs(s));
  14. m = max(maxs3,maxs)*1;
  15. s3 = s3/m;
  16. s = s/m;
  17. x = zeros(1,N); 
  18. w = ones(1,N);    
  19. Mw = 0;Me = 0;   
  20. for i=N:len
  21.     x(1:N) = s3(i:-1:i-N+1);
  22.     y(i) = x*w';
  23.     e(i) = s(i-3) - y(i);
  24.     w = w + 2*step*sign(e(i)')*x;
  25.     if max(abs(w))>Mw
  26.         Mw = max(abs(w));     
  27.     end
  28.     if max(abs(e))>Me
  29.         Me = max(abs(e));     
  30.     end
  31. end
  32. fid =fopen('D:matlab\s_in.txt','w');  
  33. for k=1:length(s_16)
  34.     s_16_Bin = dec2bin(s_16(k) + (s_16(k)<0)*2^B,B);
  35.     for q=1:B
  36.         if s_16_Bin(q)=='1'
  37.             tb = 1;
  38.         else
  39.             tb = 0;
  40.         end
  41.         fprintf(fid,'%d',tb);
  42.     end
  43.     fprintf(fid,'\r\n');
  44. end
  45. fprintf(fid,';');
  46. fclose(fid);
  47. fid = fopen('D:matlab\s3_in.txt','w');  
  48. for k=1:length(s3_16)
  49.     s3_16_Bin = dec2bin(s3_16(k) + (s3_16(k)<0)*2^B,B);
  50.     for q=1:B
  51.         if s3_16_Bin(q) == '1'
  52.             tb = 1;
  53.         else
  54.             tb = 0;
  55.         end
  56.         fprintf(fid,'%d',tb);
  57.     end
  58.     fprintf(fid,'\r\n');
  59. end
  60. fprintf(fid,';');
  61. fclose(fid);
  62. fid = fopen('D:matlab\e_out.txt','w');  
  63. fprintf(fid,'%8d\r\n',e_16);
  64. fprintf(fid,';');
  65. fclose(fid);

仿真中显示权值最大绝对值介于1、2之间,误差最大绝对值介于1、4之间,输出数据最大绝对值介于1、4之间,这些数据范围为FPGA中定点数小数位置设置了依据。

3、定点数在FPGA中的运算

在此不对定点数的定义做介绍,单介绍其加减法运算。

在verilog中,所有二进制数都当成整数来处理,所以当一个小数想要进行加减运算时需要先对其进行量化,扩展到整数形式,那么这就会产生量化误差问题,这里不对其过多讨论,而是重点讨论如何判断小数点的位置问题。在设计verilog程序时,我们需要有意地设计定点数的小数点位置,例如:两个二进制数00101与00110,逐位相加结果为01011,表示5+6=11;如果小数点均看成在最高位与次高位之间,即0∆0101、0∆0110、0∆1011,则表示0.3125+0.375=0.6875,结果也正确;但如果是0∆0101、00∆101进行加法预算,如果直接逐位相加,若小数点位置与第一个数相同,则表示0.6875,若小数点位置与第二个数相同,则表示1.375,显然结果不正确;从而说明二进制小数的加法与十进制一样,都需要对齐小数点。因为实际上计算的都是00101+00110,也就是量化后的二进制数据,如果不对齐小数点,则计算结果必然出错。

4、自适应均衡器的verilog实现

根据符号LMS算法及自适应均衡器的原理,运算步骤如下:

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        y_{1}(n) = W_{1}^{H}(n)X(n)

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        e_{2}(n) = d(n) - y_{2}(n)

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        \Delta W_{3}(n) = u\times X(n)sign[e^{*}(n)]

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        W(n+1) = W(n) + \Delta W_{4}(n)

输入数据和权值均为16bit向量。由于X(n)和d(n)数据范围均在±1之内,故小数点位于15位与14位之间;W(n)的范围在±2之内,故小数点位于14位与13位之间;y(n)及误差e(n)的范围在±4之内,故小数点在13位与12位之间;

Verilog代码如下:

  1. module Equalizer
  2. (
  3.       input rst                    ,    
  4.       input clk                    ,    
  5.       input signed [15:0]     Xin ,    
  6.       input signed [15:0]     Rin ,    
  7.       output signed [15:0] Error,    
  8.       output signed [15:0] Yout     
  9. );
  10. reg [2:0] count;
  11. always@(posedge clk or negedge rst)
  12.       if(rst == 1'b0)
  13.            count <= 3'd0;
  14.       else if(count == 3'd5)
  15.            count <= 3'd0;
  16.       else    
  17.            count <= count + 1'b1;
  18. reg signed [15:0] Xin_Reg[6:0];
  19. reg signed [15:0] Rin_Reg[6:0];
  20. reg [2:0] i,j;
  21. always@(posedge clk or negedge rst)
  22.       if(rst == 1'b0)
  23.            begin
  24.                  for(i=0;i<7;i=i+1)
  25.                       begin
  26.                             Xin_Reg[i] <= 16'd0;
  27.                             Rin_Reg[i] <= 16'd0;
  28.                       end    
  29.            end
  30.       else
  31.            begin
  32.                  if(count == 3'd5)
  33.                       for(j=0;j<6;j=j+1)
  34.                             begin
  35.                                   Xin_Reg[j+1] <= Xin_Reg[j];
  36.                                   Rin_Reg[j+1] <= Rin_Reg[j];
  37.                             end
  38.                       Xin_Reg[0] <= Xin;
  39.                       Rin_Reg[0] <= Rin;           
  40.            end
  41. reg signed[15:0] W_Reg[6:0];
  42. reg signed[15:0] DW_Reg[6:0];
  43. reg [2:0] k,q;
  44. always@(posedge clk or negedge rst)
  45.       if(rst == 1'b0)
  46.            begin
  47.                  for(k=0;k<7;k=k+1)
  48.                       begin
  49.                             W_Reg[k] <= 16'b0010_0000_0000_0000;    
  50.                       end
  51.            end
  52.       else
  53.            begin
  54.                  if(count == 3'd5)
  55.                       for(q=0;q<7;q=q+1)
  56.                             W_Reg[q] <= W_Reg[q] + DW_Reg[q];
  57.            end
  58.         
  59. wire signed[31:0] Y_Reg[6:0];
  60. genvar v;
  61. generate             
  62.       for(v=0;v<=6;v=v+1)
  63.            begin:u
  64.                  mult u
  65.                  (
  66.                       .aclr ( !rst ),
  67.                       .clock ( clk ),
  68.                       .dataa ( Xin_Reg[v] ),
  69.                       .datab ( W_Reg[v] ),
  70.                       .result ( Y_Reg[v] )
  71.                  );
  72.            end
  73. endgenerate
  74. reg signed[34:0] Y1_out,Y2_out,Y_out;
  75. reg signed[20:0] E_out;
  76. always@(posedge clk or negedge rst)
  77.       if(rst == 1'b0)
  78.            begin
  79.                  Y1_out <= 35'd0;
  80.                  Y2_out <= 35'd0;
  81.                  E_out <= 21'd0;
  82.                  Y_out <= 35'd0;
  83.            end
  84.       else
  85.            begin
  86.                  Y1_out <= {{3{Y_Reg[0][31]}},Y_Reg[0]} + {{3{Y_Reg[1][31]}},Y_Reg[1]} + {{3{Y_Reg[2][31]}},Y_Reg[2]};
  87.                  Y2_out <= {{3{Y_Reg[3][31]}},Y_Reg[3]} + {{3{Y_Reg[4][31]}},Y_Reg[4]} + {{3{Y_Reg[5][31]}},Y_Reg[5]} + {{3{Y_Reg[6][31]}},Y_Reg[6]};
  88.                  Y_out <= Y1_out + Y2_out;
  89.            if(count == 3'd3)
  90.                 E_out <= {{5{Rin_Reg[3][15]}},Rin_Reg[3]} - Y1_out[34:14] - Y2_out[34:14];
  91.       end
  92. assign Yout = Y_out[31:16];
  93. assign Error = E_out[20:5];
  94. reg [2:0] m,n;
  95. always@(posedge clk or negedge rst)
  96.       if(rst == 1'b0)
  97.            for(m=0;m<7;m=m+1)
  98.                  DW_Reg[m] <= 16'd0;
  99.       else    
  100.            begin
  101.                  for(n=0;n<7;n=n+1)
  102.                       if(E_out[20])
  103.                             DW_Reg[n] <= -{{7{Xin_Reg[n][15]}},Xin_Reg[n][15:7]};
  104.                       else    
  105.                             DW_Reg[n] <= {{7{Xin_Reg[n][15]}},Xin_Reg[n][15:7]};
  106.            end
  107. endmodule

其中使用到的乘法器IP核配置如下:

图3 乘法器IP核配置

求取滤波器系数与输入数据乘法操作占2个周期;7个32bit加法运算分为2次并行加法以及1个32bit加法运算,前者占1个周期,后者与求e(n)的减法运算占1个周期,共占2个周期;求取\DeltaW(n)的1次判断与取反操作占1个周期;最后更新滤波器系数的加法运算占1个周期;整个符号LMS算法占6个周期,故时钟频率应该位抽样频率的6倍。

具体如图所示:

图4 各步骤所需时钟周期

三、仿真测试结果

将FPGA处理数据保存到外部txt文件,用matlab读取文件,完成仿真测试

Matlab代码如下:

  1. fid = fopen('D:Error_out.txt','r');
  2. [Cout,N_n] = fscanf(fid,'%lg',inf);
  3. fclose(fid);
  4. error = Cout/max(abs(Cout));
  5. fid = fopen('D:matlab\e_out.txt','r');
  6. [Cout,N_n] = fscanf(fid,'%lg',inf);
  7. fclose(fid);
  8. e = Cout/max(abs(Cout));
  9. Error = error(1:length(error));
  10. Se = e.^2;
  11. Serror = Error.^2;
  12. N = 1:length(error);
  13. subplot(211);plot(Serror);title('FPGA仿真误差收敛图');xlabel('数据长度');ylabel('归一化误差');
  14. subplot(212);plot(Se);title('matlab仿真误差收敛图');xlabel('数据长度');ylabel('归一化误差');

图5 仿真测试结果​​​​​​​

可见,算法收敛后,误差信号在很小的范围内波动。Matlab仿真误差收敛图与FPGA实现后的误差收敛图基本相同,说明FPGA结果接近理论值。

内容仍然有很多未解之处,也有很多地方没有完全写明白,在此先定一个草稿,未完待续…

参考文献:

[1] 杜勇.数字滤波器的MATLAB与FPGA实现——Altera/Verilog版(第二版).北京:电子工业出版社,2019

[2] 刘威,邵高平. 基于FPGA的高速低功耗自适应滤波器的实现. 数据采集与处理.2006.(B12):150-152

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/759696
推荐阅读
相关标签
  

闽ICP备14008679号