1.算法仿真效果
本系统进行了两个平台的开发,分别是:
Vivado2019.2
Quartusii18.0+ModelSim-Altera 6.6d Starter Edition
其中Vivado2019.2仿真结果如下:
Quartusii18.0+ModelSim-Altera 6.6d Starter Edition的测试结果如下:
2.算法涉及理论知识概要
16QAM软解调是一种常用的数字调制解调技术,用于将接收到的16QAM调制的信号转换为原始数据。该技术结合了16种相位和振幅的调制方式,通过软判决算法对接收信号进行解调,16QAM软解调的系统原理是将接收到的16QAM调制信号转换为软判决结果,从而恢复原始数据。软解调是一种非硬判决的解调方法,它利用接收信号的采样值和相位信息来判断信号所处的调制状态,并对其进行解调。在16QAM软解调中,接收信号经过采样后,通过比较采样值和16个调制点的距离,选择最近的调制点作为解调结果。
16QAM调制将每四个比特映射到一个复数点上,共有16种相位和振幅的调制方式。每个复数点对应一个调制符号,通过软解调,我们可以确定接收到的信号所对应的调制符号,进而推导出原始数据。
设接收信号的采样值为$r$,我们需要通过比较$r$与16个调制点的距离,选择最近的调制点。
解调过程
以下是16QAM软解调的具体步骤:
步骤1:接收信号采样
接收信号经过抽样过程,得到采样值$r$。
步骤2:计算距离
计算采样值$r$与每个调制点的距离$d_i$,其中$i=1,2,...,16$。距离可以使用欧氏距离或其他度量方法进行计算。
步骤3:选择最近的调制点
选择与采样值$r$距离最近的调制点,记为$d_{\min}$,并记录其索引$i_{\min}$。
步骤4:软判决
根据索引$i_{\min}$,确定接收信号对应的调制符号。根据调制符号,可以推导出原始数据。
数学公式示例
以下是16QAM软解调的数学公式示例:
对于接收信号的采样值$r$,与每个调制点的距离$d_i$可以计算为:
根据索引$i_{\min}$可以确定接收信号对应的调制符号,并进一步推导出原始数据。
实现16QAM软解调的难点在于选择合适的距离度量方法和判决阈值,以及在存在噪声的情况下进行准确的判决。此外,还需要解决调制点的映射问题,确保软解调能够准确还原原始数据。
总结而言,16QAM软解调是一种通过比较采样值与调制点的距离,选择最近的调制点来解调接收信号的方法。通过软解调,可以恢复原始数据并实现高效的数据传输。
3.Verilog核心程序
`timescale 1ns / 1ns module TEST; reg clk; reg rst; reg start; wire [3:0] parallel_data; wire [15:0]sin; wire [15:0]cos; wire signed[19:0] I_com; wire signed[19:0] Q_com; wire signed[15:0]I_comcos; wire signed[15:0]Q_comsin; // DUT tops_16QAM_mod top( .clk(clk), .rst(rst), .start(start), .parallel_data(parallel_data), .sin(sin), .cos(cos), .I_com(I_com), .Q_com(Q_com), .I_comcos(I_comcos), .Q_comsin(Q_comsin) ); wire signed[23:0]I_comcos2; wire signed[23:0]Q_comsin2; wire signed[7:0]o_Ifir; wire signed[7:0]o_Qfir; wire signed[15:0]o_b1; wire signed[15:0]o_b2; wire signed[15:0]o_b3; wire signed[15:0]o_b4; wire signed[3:0]o_sdout; tops_16QAM_demod top2( .clk(clk), .rst(rst), .start(start), .I_comcos(I_comcos), .Q_comsin(Q_comsin), .I_comcos2(I_comcos2), .Q_comsin2(Q_comsin2), .o_Ifir(o_Ifir), .o_Qfir(o_Qfir), .o_b1(o_b1), .o_b2(o_b2), .o_b3(o_b3), .o_b4(o_b4), .o_sdout(o_sdout) ); initial begin clk = 0; rst = 0; start = 1; #10; rst = 1; end always #5 clk <= ~clk; integer fout1; integer fout2; initial begin fout1 = $fopen("II.txt","w"); fout2 = $fopen("QQ.txt","w"); end always @ (posedge clk) begin if(rst==1) begin $fwrite(fout1,"%d\n",I_com); $fwrite(fout2,"%d\n",Q_com); end end endmodule
标签:采样,wire,FPGA,解调,signed,verilog,testbench,16QAM,调制 From: https://www.cnblogs.com/51matlab/p/17579909.html