基於FPGA的16QAM調製+軟解調系統,包含testbench,高斯通道模組,誤位元速率統計模組,可以設定不同SNR

我爱C编程發表於2024-12-10

1.演算法模擬效果

vivado2019.2模擬結果如下(完整程式碼執行後無水印):

設定SNR=8db

設定SNR=12db

和之前開發的普通16QAM調製解調系統相比,軟解調誤位元速率更低。

基於FPGA的16QAM基帶通訊系統,包含testbench,高斯通道模組,誤位元速率統計模組,可以設定不同SNR_基於fpga的實時套刻誤差測量系統的設計與實現-CSDN部落格

模擬操作步驟可參考程式配套的操作影片。

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核心程式

	// DUT
tops_16QAM_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)
    ); 
    
wire signed[15:0]o_b1;
wire signed[15:0]o_b2;
wire signed[15:0]o_b3;
wire signed[15:0]o_b4; 
 
tops_16QAM_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_b1(),
	   .o_b2(),
	   .o_b3(),
	   .o_b4(),
	   .o_sdout(o_sdout)
	   );  
	   
//4個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_020m

  

相關文章