DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2037|回复: 0
打印 上一主题 下一主题

[待整理] QPSK数字调制解调的FPGA实现,包括源程序

[复制链接]
跳转到指定楼层
楼主
发表于 2015-4-26 17:33:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
摘要:随着FPGA技术的发展,数字通信技术与FPGA的结合体现了现代数字通信系统发展的一个趋势。为了使高速通信系统更加紧凑、成本更低、减小功耗,特别是提高设备的可靠性,可采用Q P S K数字调制技术来实现,其具有频谱利用率高、频谱特性好、抗干扰性能强、传输速率快等特点。运用verilog编写在QPSK调制解调代码以及ISE自带的IP CORE在Xilinx公司的FPGA平台上测试,结果表明系统可完全实现调制解调功能,并具有集成度高和可软件升级等优点。
           
          引言:四相绝对移相键控(QPSK)技术以其抗干扰性能强、误码性能好、频谱利用率高等优点,广泛应用于数字通信系统。随着超大规模集成电路的出现,FPGA在数字通信系统中的应用日益广泛,目前已提出了多种基于FPGA实现QPSK的方法。本文基于FPGA实现直接数字频率合成(DDS),通过对DDS信号(载波信号)输出相位的控制实现调相,除DA转换外,其它过程均可以FPGA实现。QPSK调制信号是抑制载波的信号,无法用常规的锁相环或窄带滤波器直接提取参考载波,但它又不同于一些连续相位调制信号,其载波相位变化只能取有限的几个离散值,这就隐含了参考载波的相位信息。所以,可以通过非线性处理,消除信号中的调制信息,产生与原载波相位有一定关系的分量,然后再提纯该信号,恢复已被抑制的载波信号,进而完成信号的相干解调。本文所设计的QPSK调制解调器由于具有较好的频带利用率,具有体积小、功耗低、集成度高、软件可移植性强、扰干扰能力强的特点,符合未来通信技术设计的方向。
           
          1.QPSK调制的基本原理
          四相绝对移相键控QPSK是MPSK的一种特殊情况,它利用载波的四种不同相位来表征数字信息。由于每一种载波相位代表两个比特信息,故每个四进制码元又被称为双比特码元。我们把组成双比特码元的前一信息比特用a表示,后一比特信息用b表示。双比特码元中两个信息比特ab通常是按格雷码(即反射码)排列的,当ab为00时,载波相位为0°,当ab为01时,载波相位为90°,当ab为11时,载波相位为180°,当ab为10时,载波相位为270°。
           
          QPSK信号的产生分为调相法和相位选择法。由于调相法比较常用,且实际操作性更强,故在本文中,选择调相法。用调相法产生QPSK信号的组成方框图如图1所示。图中,串/并变换器将输入的二进制序列依次分为两个并行的双极性序列。设两个序列中的二进制数字分别为a和b,每一对ab称为一个双比特码元。双极性的a和b脉冲通过两个平衡调制器分别对同相载波及正交载波进行二相调制。将ab两路输出叠加,得到四相移相信号,其相位编码逻辑关系为:当双比特码元ab为11时,输出相位为315°的载波;ab为01时,输出相位为225°的载波;ab为00时,输出相位为135°的载波;ab为10时,输出相位为45°的载波,相应的对照关系如下表所示。
           
       

        数据与相位的对照关系

         

          传统的QPSK模拟调制器结构,一般采用正交调制方法。全数字调制器的实现仍采用正交调制方法,只是将模拟处理单元采用数字信号处理的算法实。QPSK采用四种不同的载波相位来表示数字信息,每个载波相位代表2比特信息,其实现有两种方法,相位选择法与正交调制法,相位选择法又分为A、B两种方式。本文采用相位选择法B方式来实现QPSK信号,如图1所示。
           
       

        图1 QPSK调制框图

         

          2.QPSK调制的MATLAB仿真
          QPSK调制的MATLAB仿真相关的代码网上有很多,本文作者自己编写了一段代码,可以简单的表示调制的原理,在此仅将代码罗列如下,相的注释已经很清楚,不再赘述。代码要综合解调部分一起研读。
          clear all;
          clc
          M=4;
          Ts=1;
          fc=5;
          N_sample=8;%每个正弦波采样点数
          N_num=300;%I Q路分别100个bit
          dt=1/fc/N_sample;
          t=0:dt:N_num*Ts-dt;
          T=dt*length(t);
          Noise=(1/500)*randn(1,length(t))*32767;%加入噪声
          py1f=zeros(1,length(t));
          py2f=zeros(1,length(t));
          for PL=1:1:700%加入噪声强度加大
              d1=sign(randn(1,N_num));
              d2=sign(randn(1,N_num));
              d=[d1;d2];
              D=reshape(d,1,[]);%D是输入的信息序列
              gt=ones(1,fc*N_sample);
              s1=sigexpand(d1,fc*N_sample);%此为符号位扩展函数,相关函数在原代码中可见
              s2=sigexpand(d2,fc*N_sample);
              b1=conv(s1,gt);
              b2=conv(s2,gt);
              s1=b1(1:length(s1));
              s2=b2(1:length(s2));
              st_qpsk_1=s1.*round(cos(2*pi*fc*t)*32767);
              st_qpsk_2=s2.*round(sin(2*pi*fc*t)*32767);
              st_qpsk=st_qpsk_1+st_qpsk_2;%定点量化后的数据
            
              %-----------------------------------------------------------
              %                                               发射信号的功率谱
              %plot((abs(fft(st_qpsk,2048))).^2);
        3.QPSK调制的FPGA实现
          QPSK的FPGA设计内部逻辑关系如下图2所示,设计最高发送信息速率为2.5Mbit/s,首先经过一个串并变换模块将信息速率减半至1.25Mbit/s,然后经过相位选择模块分别选择45 135 225 315度相角中的一个作为正弦波的初始相位,每个码片持续5个正弦波周期,由于在每个码片的开始和结束会跟其相邻的码片的相位存在差异,导致输出的信号频谱发生严重的混跌,不便于后续处理,所以在输出端口加入FIR型带通滤波器,让带外信号尽快的衰减至最小。
           
          输出的信号经过AD变换,转换成模拟信号,此时的信号可以输出到后续相关芯片进行处理,本文不再做介绍。
           

        图2 系统框图

           
          调制代码文件之间的逻辑关系入下图所示:
       

        各个文件的逻辑关系

         

          其中QPSK_CODING.V文件是调制的最上层文件其对外端口如下所示,
           
          module QPSK_CODING(clk_2_5M,clk_50M,clk_1_25M,EN,din,ready,dataout,count);
           
          input clk_2_5M,clk_50M,clk_1_25M,EN,din;
          output ready;
          output [15:0]dataout;
          output [5:0]count;
        本设计用到3种时钟,他们之间的关系如下所示,时钟在具体的硬件实现是要有2个DCM单元组成。

       

        数字时钟管理单元

         

       

        各时钟之间的关系图

         

        下图所作的仿真是假设有14bit的数据输入到改调制模块,最后经过调制器后的输出结果如下所示:

       

        经过调制后的QPSK信号波形图(未加滤波器前的输出)

         

          改设计的其他相关模块的设计上层逻辑模块如下所示:
          数据经过串并变换模块module serial_to_parallel(clk_2_5M,EN,din,ready,dataout);
        然后再经过产生正弦波模块module Produce_Sin(EN,clk_2_5M,clk_50M,datain,ready,addr,count);

        4.QPSK解调的基本原理
          在全数字实现Q P S K解调的过程中,与AD接口的前端需要很高的处理速度,但是这些处理的算法又比较简单,FPGA器件独特的并行实时处理的特点刚好可以在这里得到体现,因此,A D C以后的数字信号处理全部由FPGA来实现。考虑到QPSK相干检测比差分检测有2.3dB功率增益,选择用相干解调算法实现解调。解调方框图如下图2:
           
          本文采用的解调方案是将A/D量化得到的数字信号x(n)与NCO产生的一对相互正交的本地载波相乘,然后分别经过低通滤波器滤波得到基带信号,从中提取为同步信息,并通过载波同步模块对NCO的输出进行调整,最后经过解差分与并串转换得到调制信息。
           
       

        图2 QPSK解调框图

         

          如上图所示,载波恢复电路从接收到的Q P S K信号中,恢复出与原传输载波频率和相位相干的载波振荡信号,同时将接收的Q P S K信号分成两路,一路与恢复的载波直接相乘;另一路与移相9 0°的恢复载波相乘,乘积项分别积分,恢复的位时钟对结果进行抽样,经判决再生出原I、Q数据比特,并、串变换器将并行的I、Q数据变成串行二进制输出数据。
           
          卡斯特环法提取载波的一个方法入下图所示:
           
       

        卡斯特环法提取载波原理图

         

          5.QPSK解调的MATLAB仿真
        此代码上接QPSK调制代码,

          

          

            %----------------------------------------------------

            %                                            信道传输

            st_qpsk=st_qpsk+Noise*(PL-1);%加入噪声

            st_qpsk=round(st_qpsk/max(abs(st_qpsk))*32767);%AD采样后的数据 16比特

             

            %----------------------------------------------------

            %                                       解调 将32位宽截取到16位

            decode_qpsk_s1=round((st_qpsk.*round(cos(2*pi*fc*t)*32767))/(2^16));

            decode_qpsk_s2=round(st_qpsk.*round((sin(2*pi*fc*t))*32767)/(2^16));

          

         

            %--------------------------------------------------------

            %                                           定点FIR滤波器

          

            Num_fix=[106,372,745,1024,1024,745,372,106;];

            Num_fix_2=[1,8,23,55,109,189,298,431,581,732,867,969,1024,1024,969,867,732,581,431,298,189,109,55,23,8,1;];

            fir_output_s1=filter(Num_fix,1,decode_qpsk_s1);

            fir_output_s1=round(fir_output_s1/(2^10));%截取

            subplot(2,1,1);    plot(t,fir_output_s1);

          

            fir_output_s2=filter(Num_fix_2,1,decode_qpsk_s2);

            fir_output_s2=round(fir_output_s2/(2^10));%截取

            subplot(2,1,2);    plot(t,fir_output_s2);

            %-------------------------------------------------------------

            %                                          判决decode_s1 decode_s2

            for(k=20:40:(N_num*N_sample*fc))

                if(fir_output_s1(k)>0)

                    decode_s1(round((k)/40))=1;

                else

                    decode_s1(round((k)/40))=-1;

                end

               

                if(fir_output_s2(k)>0)

                    decode_s2(round((k)/40))=1;

                else

                    decode_s2(round((k)/40))=-1;

                end

            end

          

             %---------------------------------------------------------------

             %                                            误码率分析

             c=[decode_s1;decode_s2];

             C=reshape(c,1,[]);

             compare=C>D;

             Error=find(compare);

             E(PL)=length(Error)/N_num;%E(PL)中存放误码率

            

          

            

        end

        figure(2);

        plot(E);

         

        完整的调制解调及误码率分析可见本文附带MATLAB代码文件(QPSK_fir_compare.m)

          其中的滤波器的选择不同会直接影响到相同信噪比下的误码率参数。
        6.QPSK解调的FPGA实现
          经过调制后的数据具有50Mbit/s的信息速率,经过有符号数乘法模块,数据分别与相互正交的两正弦波相乘,相乘后的数据再经过FIR低通滤波器模块,滤除掉高频信号,经定时抽判模块生成码率为1.25Mbit/s的两列数据,最后经过并串变换模块合并为原先的2.5Mbit/s的符号速率。

        系统框图

         

          Verilog代码各个文件的逻辑关系入下图所示:
           
       

        各个文件的逻辑关系

         

          其中TEST_QPSK.V文件是测试文件,用来测试编写的Verilog代码是否正确,其中ROM文件中存放的经过MATLAB定点数仿真生成的QPSK调制数据,共有1K字节的数据量。测试文件通过没个时钟周期将ROM中存放的调制数据输出到编写的QPSKR文件中,实现解调测试。
           
          QPSK.V文件是用到的解调文件的最上层文件,其对外端口如下:
          module QPSKR(clk, en, DIN, dout, ready
                 );
           
                 input clk;
                 input en;
                 input [15:0]DIN;
                 output [1:0]dout;
                 output ready;
           
          用两路正交的相干载波去解调,可以很容易地分离这两路正交的2PSK信号。相干解调后两路并行码元a和b,经过并/串变换后,成为串行数据输出。
           
          输入的数据与已经锁定的正交载波相乘后的输出结果如下图所示,图中只列出了一路信号的输出结果。
       

        未滤波前的输出数据

         

        本文的一个设计重点在于滤波器的设计,使用MATLAB中滤波器协同设计单元,如下图所示,可以生成7阶滤波器,其系数为[0.0195568849377802      0.0684534436681266    0.136904053813160      0.188242810004127      0.188242810004127       0.136904053813160      0.0684534436681266    0.0195568849377802];

         

          经过定点量化后得到0,23170,32767,23170,0,42366,32769,42366;将其写入到coe文件中作为滤波器的抽头系数。
           
       

        FDATOOL工具输出结果

         

          经过FIR低通滤波器后的输出结果如下图所示:
       

        FIR滤波器输出的两路信号

         

          经过滤波器后的频谱如下所示,从图中可以看出带外信号已经衰减到很小值。
       

        经过滤波器后的信号频谱

         

        经过定时提取模块的抽判最后两路信号的输出结果如下,从图中我们可以看到dout输出的数据速率为1.25Mbit/s。

       

        两路解调后的数据输出

         

          总上所述,当顶层模块检测到有有效数据到达时,en信号被置为高电平,此时信号输入到后解调模块,在输出端口,当ready信号有效时,在dout端口会有有效的数据输出。输出的数据如下所示:
           
       

        上层模块中包含了如下个模块
          MUL_QPSKR mul1(clk, p1, data_out1, DIN, ce, ready1);
          MUL_QPSKR mul2(clk, p2, data_out2, DIN, ce, ready2);
          ROM_SIN sin0(clk,addr,en,ready0,data_out1, data_out2);
          FIR fir1(rfd1, rdy1, ~ready1, clk, dout1, p1[31:16]);
          FIR fir2(rfd2, rdy2, ~ready2, clk, dout2, p2[31:16]);
          judgebit judge0(clk, dout1[34], dout2[34], rdy1, rdy2, dout, ready);
           
          其中MUL_QPSKR是乘法器单元,实现有符号数乘法;ROM_SIN模块存放的正弦波数据,此模块最后可用DDS模块代替,最后是滤波器模块。本设计中最重要的一个模块CASTA载波提取还在编写中,暂时还不能提交相关代码。
           
          滤波器模块是本设计的关键,如果提高相同信噪比条件下的误码率可以提高滤波器的阶数,但会相应的提高器件实现的复杂度,也即提高FPGA器件的面积。
           
          7.结语
          目前,全数字调制解调器使得通信设备紧凑、成本低、功耗小,且可靠性高。高速数字通信系统多采用Q P S K调制方式,可获得较高的信噪比,又有较高的频带效率。但专用Q P S K芯片的通用性较差,价格较贵。通用Q P S K芯片大多基于D S P芯片,运算量较大和受硬件的限制。用FPGA是实现通用Q P S K的最佳途径,所有参数均由用户设置,提高了通信设备的灵活性和通用性。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-12-29 12:38 , 耗时 0.092259 秒, 21 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表