m基于FPGA的QPSK软解调verilog实现,含testbench和MATLAB辅助验证程序

目录

1.算法仿真效果

2.算法涉及理论知识概要

3.Verilog核心程序

4.完整算法代码文件


1.算法仿真效果


本系统进行了两个平台的开发,分别是:

Vivado2019.2

Quartusii18.0+ModelSim-Altera 6.6d  Starter Edition

其中Vivado2019.2仿真结果如下:

 

 Quartusii18.0+ModelSim-Altera 6.6d  Starter Edition的测试结果如下:

 

matlab测试:

2.算法涉及理论知识概要

       QPSK是一种常用的调制方式,通过将两个比特映射到一个复平面上的相位点,实现了高效的信号传输。软解调是一种基于接收信号的概率估计进行解调的方法,能够提供更好的性能。本文将逐步介绍QPSK软解调的实现过程,包括信号采样、相位估计、判决和解调等方面。软解调是一种通过概率估计实现解调的方法,能够在信道噪声存在的情况下提供更好的性能。QPSK是一种常用的调制方式,通过将两个比特映射到相位点,实现了高效的信号传输。本文旨在详细介绍QPSK软解调的实现过程,包括信号采样、相位估计、判决和解调等步骤。

实现步骤
2.1 信号采样

       接收到的QPSK信号经过采样操作,得到离散时间信号序列。采样率需要满足奈奎斯特采样定理,通常为比特速率的两倍。
2.2 判决

       在QPSK信号解调中,判决过程用于确定每个信号符号的二进制比特值。判决过程根据接收信号的相位进行划分,将其映射到不同的比特值。
       假设接收到的信号序列为r[n],判决过程的结果为判决符号d_hat。常见的判决公式为:
if theta_hat > -pi/4 && theta_hat <= pi/4
d_hat = [1, 1]
elseif theta_hat > pi/4 && theta_hat <= 3pi/4
d_hat = [0, 1]
elseif theta_hat > 3pi/4 || theta_hat <= -3*pi/4
d_hat = [0, 0]
else
d_hat = [1, 0]
end
2.3 解调

         解调过程将判决的比特值转换为原始数据比特。解调过程根据映射表将判决比特值转换为原始数据比特。假设判决比特值为d_hat,解调过程的结果为解调比特d。常见的解调公式为:
if d_hat == [1, 1]
d = [0, 0]
elseif d_hat == [0, 1]
d = [0, 1]
elseif d_hat == [0, 0]
d = [1, 0]
else
d = [1, 1]
end

2.4 软解调

        软解调是QPSK软解调的关键步骤,它利用判决符号和相位估计的结果进行概率估计,以提高解调的准确性。假设判决符号为d_hat,软解调过程的结果为软解调符号d。常见的软解调公式为: d = d_hat / P(d_hat|r[n])

        其中P(d_hat|r[n])表示在接收到信号r[n]的条件下,判决符号d_hat为d_hat的概率。该概率可以通过估计信号点的概率分布函数或使用最大似然估计等方法得到。软解调过程需要进行概率估计,以提高解调的准确性。这涉及到估计信号点的概率分布函数或使用其他概率估计方法,其中噪声的影响需要被适当地考虑。

3.Verilog核心程序

`timescale 1ns / 1ps


module TEST();

reg i_clk;
reg i_clkSYM;
reg i_rst;
reg i_dat;
 

wire signed[15:0]o_Ifir_T;
wire signed[15:0]o_Qfir_T;
wire signed[15:0]o_cos_T;
wire signed[15:0]o_sin_T;
wire signed[31:0]o_modc_T;
wire signed[31:0]o_mods_T;
wire signed[31:0]o_mod_T;

wire signed[15:0]o_cos_R;
wire signed[15:0]o_sin_R;
wire signed[31:0]o_modc_R;
wire signed[31:0]o_mods_R;
wire signed[31:0]o_Ifir_R;
wire signed[31:0]o_Qfir_R;
wire signed[15:0]o_b1;
wire signed[15:0]o_b2;
wire signed[15:0]o_dat;
//QPSK调制
TQPSK TQPSKU(
.i_clk  (i_clk),
.i_clkSYM(i_clkSYM),
.i_rst  (i_rst),
.i_dat(i_dat),
 

.o_Ifir (o_Ifir_T),
.o_Qfir (o_Qfir_T),
.o_cos  (o_cos_T),
.o_sin  (o_sin_T),
.o_modc (o_modc_T),
.o_mods (o_mods_T),
.o_mod  (o_mod_T)
);


//QPSK解调
RQPSK RQPSKU(
.i_clk  (i_clk),
.i_rst  (i_rst),
.i_clkSYM(i_clkSYM),
.i_med  (o_mod_T[25:10]),
.o_cos  (o_cos_R),
.o_sin  (o_sin_R),
.o_modc (o_modc_R),
.o_mods (o_mods_R),
.o_Ifir (o_Ifir_R),
.o_Qfir (o_Qfir_R),
.o_b1   (o_b1),
.o_b2   (o_b2),
.o_dat  (o_dat)
);

initial
begin
    i_clk = 1'b1;
    i_clkSYM=1'b1;
    i_rst = 1'b1;
    #1600
    i_rst = 1'b0;
end

always #5 i_clk=~i_clk;
always #80 i_clkSYM=~i_clkSYM;


initial
begin
    i_dat = 1'b0;
    #1440
    repeat(10)
    begin
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b0;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b1;
    #160 i_dat = 1'b0;
    
    
    end
    $stop();
end
//reg[7:0]cmnts;
//always @(posedge i_clk or posedge i_rst)
//begin
//     if(i_rst)
//	  begin
//	  cmnts <= 8'd0;
//	  i_Ibits_T<=1'b0;
//	  i_Qbits_T<=1'b0;
//	  end
//else begin
//	  cmnts <= cmnts + 8'd1;
//	  i_Ibits_T<=cmnts[5];
//	  i_Qbits_T<=cmnts[6];
//     end
//end



endmodule
00_026m

4.完整算法代码文件

V

猜你喜欢

转载自blog.csdn.net/hlayumi1234567/article/details/131730855
今日推荐