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

这篇具有很好参考价值的文章主要介绍了自适应均衡器的原理与实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

目录

一、自适应均衡器的原理

1、LMS算法

2、LMS算法的原理

3、符号LMS算法

二、自适应均衡器实现

1、matlab仿真

2、产生测试数据

3、定点数在FPGA中的运算

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

三、仿真测试结果

一、自适应均衡器的原理

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

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

1、LMS算法

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

式中,

2、LMS算法的原理

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

                                                ​​​​​​​        ​​​​​​​        

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​自适应均衡,fpga开发,信号处理,matlab

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

自适应均衡,fpga开发,信号处理,matlab

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

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

3、符号LMS算法

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

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        自适应均衡,fpga开发,信号处理,matlab

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

二、自适应均衡器实现

1、matlab仿真

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

Matlab代码如下:

len = 20000;   
Tlen = 2000;   
step = 1/128;  

s = zeros(1,len);  
s1 = zeros(1,len); 
x = zeros(1,N);    
w = ones(1,N);    

s = randsrc(1,len);
s1(2:len) = s(1:len-1);

p = 0.1;
SNR = [0:10];
for db = 1:length(SNR)
    s2 = sqrt(1-p)*s + sqrt(p)*s1;
        s3 = awgn(s2,db,'measured');
    for i=N:len
        x(1:N) = s3(i:-1:i-N+1);   
        y(i) = x*w';              
        e(i) = s(i-3) - y(i);      
        w = w + 2*step*sign(x)*e(i)';
        if y(i)>0
            y1(i) = 1;
        else
            y1(i) = -1;
        end
        if s3(i)>0
            y2(i) = 1;
        else
            y2(i) = -1;
        end
    end
   errornum1 = sum(y1(Tlen:end)~=s(Tlen-3:end-3)); 
   errornum2 = sum(y2(Tlen:end)~=s(Tlen:end));
   ber1(db) = errornum1/(len-Tlen);
   ber2(db) = errornum2/(len-Tlen);
end

subplot(121);
semilogy(SNR,ber1,'+-',SNR,ber2,'-');
xlabel('信噪比(SNR)');ylabel('误码率');title('信噪比与误码率的关系(P=0.1)');
legend('有均衡器','无均衡器');

db=10;
p=[0:0.05:1];
for m=1:length(p)
    s2=sqrt(1-m*0.05)*s+sqrt(m*0.05)*s1;
    s3=awgn(s2,db,'measured');
    for i=N:len
        x(1:N)=s3(i:-1:i-N+1);
        y(i)=x*w';
        e(i)=s(i-3)-y(i);
        w=w+2*step*sign(x)*e(i)';
        if y(i)>0
            y1(i)=1;
        else
            y1(i)=-1;
        end
        if s3(i)>0
            y2(i)=1;
        else
            y2(i)=-1;
        end
    end
    errornum1=sum(y1(Tlen:end)~=s(Tlen-3:end-3));
    errornum2=sum(y2(Tlen:end)~=s(Tlen:end));
    ber3(m)=errornum1/(len-Tlen);
    ber4(m)=errornum2/(len-Tlen);
end

subplot(122);
semilogy(p,ber3,'+-',p,ber4,'-');
xlabel('多径损耗(P)');ylabel('误码率');title('多径损耗因子与误码率的关系 (SNR=10dB)');
legend('有均衡器 ','无均衡器');

自适应均衡,fpga开发,信号处理,matlab

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

2、产生测试数据

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

Matlab代码如下:

len = 2000;       
step = 1/128;     
N = 7;            
B = 16;     
p = 0.1;           
SNR = 10;         

s = randsrc(1,len);
s1 = zeros(1,len); 
s1(2:len) = s(1:len-1);
s2 = sqrt(1-p)*s + sqrt(p)*s1; 
s3 = awgn(s2,SNR,'measured'); 

maxs3 = max(abs(s3));  
maxs = max(abs(s));
m = max(maxs3,maxs)*1;
s3 = s3/m;
s = s/m;
x = zeros(1,N); 
w = ones(1,N);    
Mw = 0;Me = 0;   

for i=N:len
    x(1:N) = s3(i:-1:i-N+1);
    y(i) = x*w';
    e(i) = s(i-3) - y(i);
    w = w + 2*step*sign(e(i)')*x;
    if max(abs(w))>Mw
        Mw = max(abs(w));     
    end
    if max(abs(e))>Me
        Me = max(abs(e));     
    end
end

fid =fopen('D:matlab\s_in.txt','w');  
for k=1:length(s_16)
    s_16_Bin = dec2bin(s_16(k) + (s_16(k)<0)*2^B,B);
    for q=1:B
        if s_16_Bin(q)=='1'
            tb = 1;
        else
            tb = 0;
        end
        fprintf(fid,'%d',tb);
    end
    fprintf(fid,'\r\n');
end
fprintf(fid,';');
fclose(fid);

fid = fopen('D:matlab\s3_in.txt','w');  
for k=1:length(s3_16)
    s3_16_Bin = dec2bin(s3_16(k) + (s3_16(k)<0)*2^B,B);
    for q=1:B
        if s3_16_Bin(q) == '1'
            tb = 1;
        else
            tb = 0;
        end
        fprintf(fid,'%d',tb);
    end
    fprintf(fid,'\r\n');
end
fprintf(fid,';');
fclose(fid);

fid = fopen('D:matlab\e_out.txt','w');  
fprintf(fid,'%8d\r\n',e_16);
fprintf(fid,';');
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算法及自适应均衡器的原理,运算步骤如下:

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        

        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        自适应均衡,fpga开发,信号处理,matlab

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

Verilog代码如下:

module Equalizer
(
      input rst                    ,    
      input clk                    ,    
      input signed [15:0]     Xin  ,    
      input signed [15:0]     Rin  ,    

      output signed [15:0]    Error,    
      output signed [15:0]    Yout     
);

reg [2:0] count;
always@(posedge clk or negedge rst)
      if(rst == 1'b0)
           count <= 3'd0;
      else if(count == 3'd5)
           count <= 3'd0;
      else    
           count <= count + 1'b1;

reg signed [15:0] Xin_Reg[6:0];
reg signed [15:0] Rin_Reg[6:0];
reg [2:0] i,j;
always@(posedge clk or negedge rst)
      if(rst == 1'b0)
           begin
                 for(i=0;i<7;i=i+1)
                      begin
                            Xin_Reg[i] <= 16'd0;
                            Rin_Reg[i] <= 16'd0;
                      end    
           end
      else
           begin
                 if(count == 3'd5)
                      for(j=0;j<6;j=j+1)
                            begin
                                  Xin_Reg[j+1] <= Xin_Reg[j];
                                  Rin_Reg[j+1] <= Rin_Reg[j];
                            end
                      Xin_Reg[0] <= Xin;
                      Rin_Reg[0] <= Rin;           
           end

reg signed[15:0] W_Reg[6:0];
reg signed[15:0] DW_Reg[6:0];
reg [2:0] k,q;
always@(posedge clk or negedge rst)
      if(rst == 1'b0)
           begin
                 for(k=0;k<7;k=k+1)
                      begin
                            W_Reg[k] <= 16'b0010_0000_0000_0000;    
                      end
           end
      else
           begin
                 if(count == 3'd5)
                      for(q=0;q<7;q=q+1)
                            W_Reg[q] <= W_Reg[q] + DW_Reg[q];
           end
        
wire signed[31:0] Y_Reg[6:0];
genvar v;
generate             
      for(v=0;v<=6;v=v+1)
           begin:u
                 mult u
                 (
                      .aclr ( !rst ),
                      .clock ( clk ),
                      .dataa ( Xin_Reg[v] ),
                      .datab ( W_Reg[v] ),
                      .result ( Y_Reg[v] )
                 );
           end
endgenerate

reg signed[34:0] Y1_out,Y2_out,Y_out;
reg signed[20:0] E_out;
always@(posedge clk or negedge rst)
      if(rst == 1'b0)
           begin
                 Y1_out <= 35'd0;
                 Y2_out <= 35'd0;
                 E_out <= 21'd0;
                 Y_out <= 35'd0;
           end
      else
           begin
                 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]};
                 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]};
                 Y_out <= Y1_out + Y2_out;
           if(count == 3'd3)
                 E_out <= {{5{Rin_Reg[3][15]}},Rin_Reg[3]} - Y1_out[34:14] - Y2_out[34:14];
      end
assign Yout = Y_out[31:16];
assign Error = E_out[20:5];

reg [2:0] m,n;
always@(posedge clk or negedge rst)
      if(rst == 1'b0)
           for(m=0;m<7;m=m+1)
                 DW_Reg[m] <= 16'd0;
      else    
           begin
                 for(n=0;n<7;n=n+1)
                      if(E_out[20])
                            DW_Reg[n] <= -{{7{Xin_Reg[n][15]}},Xin_Reg[n][15:7]};
                      else    
                            DW_Reg[n] <= {{7{Xin_Reg[n][15]}},Xin_Reg[n][15:7]};
           end
endmodule

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

自适应均衡,fpga开发,信号处理,matlab

图3 乘法器IP核配置

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

具体如图所示:

自适应均衡,fpga开发,信号处理,matlab

图4 各步骤所需时钟周期

三、仿真测试结果

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

Matlab代码如下:

fid = fopen('D:Error_out.txt','r');
[Cout,N_n] = fscanf(fid,'%lg',inf);
fclose(fid);
error = Cout/max(abs(Cout));

fid = fopen('D:matlab\e_out.txt','r');
[Cout,N_n] = fscanf(fid,'%lg',inf);
fclose(fid);
e = Cout/max(abs(Cout));

Error = error(1:length(error));
Se = e.^2;
Serror = Error.^2;

N = 1:length(error);
subplot(211);plot(Serror);title('FPGA仿真误差收敛图');xlabel('数据长度');ylabel('归一化误差');
subplot(212);plot(Se);title('matlab仿真误差收敛图');xlabel('数据长度');ylabel('归一化误差');

自适应均衡,fpga开发,信号处理,matlab

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

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

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

参考文献:

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

[2] 刘威,邵高平. 基于FPGA的高速低功耗自适应滤波器的实现. 数据采集与处理.2006.(B12):150-152文章来源地址https://www.toymoban.com/news/detail-777748.html

到了这里,关于自适应均衡器的原理与实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springCloud-LoadBalancer负载均衡微服务负载均衡器LoadBalancer

    2020年前SpringCloud是采用Ribbon作为负载均衡实现,但是在2020后采用了LoadBalancer替代 1.RandomLoadBalancer-随机分配策略 2.RoundRobinLoadBalancer-轮询分配策略(默认)

    2024年04月15日
    浏览(41)
  • 高可用keepalived + Nginx 负载均衡器

    准备操作: [root@localhost ~]# systemctl stop firewalld  # 或 systemctl disable --now firewalld [root@localhost ~]# setenforce 0 [root@localhost ~]# cd /etc/yum.repos.d [root@localhost ~]# mv repo.bak/* ./ [root@localhost ~]# yum -y install epel-release [root@localhost ~]# yum install -y keepalived nginx         #epel下载的旧版nginx 没有str

    2024年02月01日
    浏览(38)
  • 磁盘均衡器:HDFS Disk Balancer

    相比较于个人PC,服务器一般可以通过挂载多块磁盘来扩大单机的存储能力 在Hadoop HDFS中,DataNode负责最终数据block的存储,在所在机器上的磁盘之间分配数据块。当写入新block时,DataNodes将根据选择策略(循环策略或可用空间策略)来选择block的磁盘(卷) 循环策略:它将新

    2024年02月14日
    浏览(29)
  • SpringCloud LoadBalancer 新一代负载均衡器

    工作中使用 OpenFeign 进行跨服务调用,最近发现线上经常会遇到请求失败。 通过排查我们发现不是接口超时,而是有时候会请求到已经下线的服务导致报错。这多发生在服务提供者系统部署的时候,因为系统部署的时候会调用 Spring 容器 的 shutdown() 方法, Eureka Server 那里能够

    2023年04月22日
    浏览(39)
  • 负载均衡器 OpenELB ARP 欺骗技术解析

    作者:大飞哥,视源电子运维工程师,KubeSphere 用户委员会广州站站长,KubeSphere Ambassador。 K8S 对集群外暴露服务有三种方式:NodePort,Ingress 和 Loadbalancer。NodePort 用于暴露 TCP 服务(4 层),但限于对集群节点主机端口的占用,不适合大规模使用;Ingress 用于暴露 HTTP 服务(7 层),

    2024年02月01日
    浏览(45)
  • DAY 50 LVS负载均衡器 NAT模式

    Cluster,集群、群集 由多台主机构成,但对外只表现为一一个整体,只提供一-个访问入口(域名或IP地址), 相当于一台大型计算机。 互联网应用中,随着站点对硬件性能、响应速度、服务稳定性、数据可靠性等要求越来越高,单台服务器已经无法满足负载均衡及高可用的要求

    2024年02月02日
    浏览(50)
  • 选择正确的负载均衡器:LVS还是Nginx?

    💡一个热爱分享高性能服务器后台开发知识的博主,目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。技能涵盖了多个领域,包括C/C++、Linux、Nginx、MySQL、Redis、fastdfs、kafka、Docker、TCP/IP、协程、DPDK等。 👉 🎖️ CSDN实力新星,社区专家

    2024年02月13日
    浏览(38)
  • 【kubernetes】负载均衡器安装部署-Haproxy与keepalived

    前言 :二进制部署kubernetes集群在企业应用中扮演着非常重要的角色。无论是集群升级,还是证书设置有效期都非常方便,也是从事云原生相关工作从入门到精通不得不迈过的坎。通过本系列文章,你将从虚拟机准备开始,到使用二进制方式从零到一搭建起安全稳定的高可用

    2024年02月10日
    浏览(36)
  • ADS仿真,3db均衡器是否可以补偿3db插入损耗?

    高速信号走线经常会有走线超长的问题,走线过长带来的直接影响是对应的插入损耗IL会增加,当超过标准要求时需增加Redriver等补偿,最常用的调整时增加预加重和去加重。而调整预加重时首先遇到的一个问题是补偿多少db? http://www.eepw.com.cn/article/237872.htm 使用ADS 眼图仿真,

    2024年02月07日
    浏览(47)
  • [11]云计算|简答题|案例分析|云交付|云部署|负载均衡器|时间戳

    我们学校要根据目前学生互联网在线学习、教师教学资源电子化、教学评价过程化精细化的需求,计划升级为云教学系统。请同学们根据学校发展实际考虑云交付模型包含哪些?云部署采用什么模型最合适?请具体说明。 A公司有20人,行政人员5人,科研和技术人员15人。现接

    2024年02月03日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包