1.算法仿真效果
vivado2019.2仿真结果如下(完整代码运行后无水印):
设置SNR=40db:
将数据导入matlab,显示其星座图:
设置SNR=32db:
将数据导入matlab,显示其星座图:
设置SNR=24db:
将数据导入matlab,显示其星座图:
系统RTL结构如下:
仿真操作步骤可参考程序配套的操作视频。
2.算法涉及理论知识概要
256QAM(Quadrature Amplitude Modulation,正交幅度调制)是一种高级调制方案,能够在给定带宽内传输更多的信息比特。256QAM意味着每个符号可以携带8个比特的信息,因为 log2(256)=8log2(256)=8。
在调制过程中,输入比特流首先被映射到复数值星座图上的特定点。对于256QAM,每个符号代表8个比特信息。调制器根据输入比特选择对应的星座点,并将这些星座点转换成相应的复数形式。例如,在理想情况下,256QAM星座图包含256个不同的点。
256QAM的星座图是一个二维平面内的点阵,每个点代表一个独特的调制状态。在理想情况下,星座图中的每个点都对应于一个特定的复数值,该值由相位和幅度共同决定。由于256QAM有256个可能的状态,因此其星座图包含256个点。
256QAM映射过程如下:
数据编码:首先,输入的一组8比特数据需要被编码成一个复数形式的符号。这意味着每个256QAM符号实际上是由8比特信息组成的。
星座图映射:接下来,这8比特被映射到星座图上的一个特定位置。通常,这些比特会按照一定的规则分配给星座图的不同维度。例如,前4比特可以确定星座图上的一维坐标(实部),而后4比特确定另一维坐标(虚部)。
星座点分配:具体来说,星座图上的每个点都有一个特定的坐标(I,Q),其中I 表示同相分量,Q 表示正交分量。在256QAM中,这些坐标可以从一系列预定义的值中选取。在标准化的256QAM星座图中,I 和 Q 的取值范围通常是−7,−5,−3,−1,1,3,5,7−7,−5,−3,−1,1,3,5,7 或者类似的比例因子乘以这些值。
星座图结构:256QAM星座图通常呈格状排列,每个点在I-Q 平面上的位置决定了其代表的比特组合。例如,如果使用灰度编码(Gray coding)来减少相邻星座点之间的比特翻转数,那么每个点周围的8个邻居将与其仅有一个比特的不同。
在接收端,接收到的复数信号经过解调处理,将其映射回最接近的星座点,然后恢复出原始比特序列。这个过程可能会受到信道引入的噪声和失真的影响,导致错误的发生。
3.Verilog核心程序``` // DUT
tops_256QAM_mod top(
.clk(clk),
.rst(rst),
.start(start),
.parallel_data(parallel_data),
.sin(sin),
.cos(cos),
.I_com(),
.Q_com(),
.I_comcos(I_com),//基带方式输出,即实际通信中的复数模式
.Q_comsin(Q_com)
);
//加入信道
//实部
awgns awgns_u1(
.i_clk(clk),
.i_rst(~rst),
.i_SNR(i_SNR), //这个地方可以设置信噪比,数值大小从-10~50,
.i_din(I_com),
.o_noise(),
.o_dout(I_Ncom)
);
//虚部
awgns awgns_u2(
.i_clk(clk),
.i_rst(~rst),
.i_SNR(i_SNR), //这个地方可以设置信噪比,数值大小从-10~50,
.i_din(Q_com),
.o_noise(),
.o_dout(Q_Ncom)
);
tops_256QAM_demod top2(
.clk(clk),
.rst(rst),
.start(start),
.I_Ncom(I_Ncom),
.Q_Ncom(Q_Ncom),
.I_comcos2(I_comcos2),
.Q_comsin2(Q_comsin2),
.o_Ifir(o_Ifir),
.o_Qfir(o_Qfir),
.o_sdout(o_sdout),
.flag_reg(flag_reg)
);
//6个bit同时统计误码率
wire signed[31:0]o_error_num1;
wire signed[31:0]o_total_num1;
Error_Chech Error_Chech_u1(
.i_clk(clk),
.i_rst(~rst),
.i_trans(parallel_data),
.i_rec(o_sdout),
.o_error_num(o_error_num1),
.o_total_num(o_total_num1)
);
assign o_total_num = o_total_num1;
assign o_error_num = o_error_num1;
endmodule
0sj_014m
```