1.算法仿真效果
本課題是在博主以前寫的文章《m基于FPGA的64QAM調制解調通信系統(tǒng)verilog實現,包含testbench,不包含載波同步》的升級纵散,升級內容包括信道模塊(可以設置SNR)映挂,誤碼率統(tǒng)計茬故,同時修正了數據輸入頻率問題破加,從而提升了系統(tǒng)的仿真效率。
vivado2019.2仿真結果如下(完整代碼運行后無水优ァ):
設置SNR=15
導入matlab浙炼,顯示星座圖:
設置SNR=20
導入matlab,顯示星座圖:
設置SNR=25
導入matlab土童,顯示星座圖:
系統(tǒng)RTL結構如下:
仿真操作步驟可參考程序配套的操作視頻诗茎。
2.算法涉及理論知識概要
隨著無線通信技術的不斷發(fā)展,越來越多的應用需要高速献汗、高可靠性的通信系統(tǒng)來傳輸數據敢订。調制解調是一種常用的數字通信技術,它可以將數字信號轉換成模擬信號進行傳輸罢吃,同時也可以將接收到的模擬信號轉換成數字信號進行處理楚午。在數字調制解調中,QAM是一種常用的調制方式尿招,它可以將數字信號分為實部和虛部兩個部分進行編碼矾柜,從而實現高效的數據傳輸。本文旨在介紹基于FPGA的64QAM調制解調通信系統(tǒng)的設計和實現泊业,包括信號生成把沼、信號調制、信號解調和誤碼率測試等環(huán)節(jié)吁伺,以驗證系統(tǒng)的可行性和性能饮睬。
2.1 64QAM調制解調系統(tǒng)的設計
在64QAM調制解調系統(tǒng)中,需要生成一定數量的數字信號篮奄,作為調制信號和參考信號捆愁。數字信號可以使用隨機數生成器產生,也可以使用特定的算法生成窟却。在本文中昼丑,我們采用了帶噪聲的隨機數生成器產生數字信號,其中噪聲是為了模擬實際通信中的信道噪聲夸赫。
在64QAM調制解調系統(tǒng)中菩帝,需要將數字信號轉換成模擬信號進行傳輸,這個過程稱為信號調制。在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同時統(tǒng)計誤碼率 ???
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