基于FPGA的64QAM基带通信系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR

1.算法仿真效果

      本课题是在博主以前写的文章《m基于FPGA的64QAM调制解调通信系统verilog实现,包含testbench,不包含载波同步》的升级,升级内容包括信道模块(可以设置SNR),误码率统计,同时修正了数据输入频率问题,从而提升了系统的仿真效率。

 

vivado2019.2仿真结果如下(完整代码运行后无水印):

 

设置SNR=15

 

 

 

导入matlab,显示星座图:

 

 

 

设置SNR=20

 

 

 

导入matlab,显示星座图:

 

 

 

设置SNR=25

 

 

 

导入matlab,显示星座图:

 

 

 

系统RTL结构如下:

 

 

 

仿真操作步骤可参考程序配套的操作视频。

 

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

       随着无线通信技术的不断发展,越来越多的应用需要高速、高可靠性的通信系统来传输数据。调制解调是一种常用的数字通信技术,它可以将数字信号转换成模拟信号进行传输,同时也可以将接收到的模拟信号转换成数字信号进行处理。在数字调制解调中,QAM是一种常用的调制方式,它可以将数字信号分为实部和虚部两个部分进行编码,从而实现高效的数据传输。本文旨在介绍基于FPGA的64QAM调制解调通信系统的设计和实现,包括信号生成、信号调制、信号解调和误码率测试等环节,以验证系统的可行性和性能。

 

2.1 64QAM调制解调系统的设计

        64QAM调制解调系统中,需要生成一定数量的数字信号,作为调制信号和参考信号。数字信号可以使用随机数生成器产生,也可以使用特定的算法生成。在本文中,我们采用了带噪声的随机数生成器产生数字信号,其中噪声是为了模拟实际通信中的信道噪声。

        64QAM调制解调系统中,需要将数字信号转换成模拟信号进行传输,这个过程称为信号调制。在QAM调制中,数字信号分为实部和虚部两个部分进行编码,然后将它们分别调制到不同的载波上,最后将两个载波叠加在一起。具体来说,假设数字信号为s(n),其中n表示信号的采样点,QAM调制可以表示为:

 

基带I路

 

 

 

基带Q路

 

 

 

       其中,s_I(n)表示实部信号,s_Q(n)表示虚部信号,A_I和A_Q分别表示实部和虚部的调制系数,f_c表示载波频率,t(n)表示采样时间。在64QAM调制中,实部和虚部分别采用8QAM调制,然后叠加在一起,最终得到64QAM调制信号。

 

2.2 信号解调

        在接收端,需要将接收到的模拟信号转换成数字信号进行处理,这个过程称为信号解调。在64QAM解调中,首先需要将接收到的实部和虚部,进行8QAM解调,最后将解调后的实部和虚部重新组合成数字信号。

 

3.verilog核心程序

	// DUT
tops_64QAM_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_64QAM_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)
	   );  
	   
//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_013m

  

posted @ 2024-10-23 19:55  我爱C编程  阅读(9)  评论(0编辑  收藏  举报