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

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

1.演算法模擬效果

本程式工程在我以前寫的《m基於FPGA的16QAM調製解調通訊系統verilog實現,包含testbench,不包含載波同步》基礎上增加了通道模組,誤位元速率統計模組,可以設定不同的SNR,模擬測試該FPGA系統的誤碼效能。

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

設定SNR=8db

設定SNR=12db

設定SNR=16db

RTL結構圖:

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

2.演算法涉及理論知識概要

16QAM全稱正交幅度調製是英文Quadrature Amplitude Modulation的縮略語簡稱,意思是正交幅度調製,是一種數字調製方式。產生的方法有正交調幅法和複合相移法。16QAM是指包含16種符號的QAM調製方式。

16QAM 調製原理

16QAM 是用兩路獨立的正交 4ASK 訊號疊加而成,4ASK 是用多電平訊號去鍵控載波而得到的訊號。它是 2ASK 調製的推廣,和 2ASK 相比,這種調製的優點在於資訊傳輸速率高。

正交幅度調製是利用多進位制振幅鍵控(MASK)和正交載波調製相結合產生的。

16 進位制的正交振幅調製是一種振幅相位聯合鍵控訊號。16QAM 的產生有 2 種方法:

1)正交調幅法,它是有 2 路正交的四電平振幅鍵控訊號疊加而成;

2)複合相移法:它是用 2 路獨立的四相位移相鍵控訊號疊加而成。

這裡採用正交調幅法。

數字訊號是透過FPGA的輸出埠生成的。在16QAM調製中,每個符號包含4個位元,因此需要一個4位二進位制計數器來生成數字訊號。計數器的輸出被對映到星座圖上的一個點,然後透過數字到模擬轉換器(DAC)轉換為模擬訊號。串/並變換器將速率為Rb的二進位制碼元序列分為兩路,速率為Rb/2.2-4電平變換為Rb/2 的二進位制碼元序列變成速率為RS=Rb/log216 的 4 個電平訊號,4 電平訊號與正交載波相乘,完成正交調製,兩路訊號疊加後產生 16QAM訊號.在兩路速率為Rb/2 的二進位制碼元序列中,經 2-4 電平變換器輸出為 4 電平訊號,即M=16.經 4 電平正交幅度調製和疊加後,輸出 16 個訊號狀態,即 16QAM.

16QAM 解調原理

16QAM 訊號採取正交相干解調的方法解調,解調器首先對收到的 16QAM 訊號進行正交相干解調,一路與 cos ω c t 相乘,一路與 sin ω c t 相乘。然後經過低通濾波器,低通濾波器 LPF 濾除乘法器產生的高頻分量,獲得有用訊號,低通濾波器LPF 輸出經抽樣判決可恢復出電平訊號。

3.verilog核心程式

module TOPS_16QAM(
  input clk,
  input rst,
  input start,
  input signed[7:0]i_SNR,
  output  [3:0] parallel_data,
  output signed[15:0]sin,
  output signed[15:0]cos,
  output  signed[15:0]  I_com,
  output  signed[15:0]  Q_com,
  output  signed[15:0]I_Ncom,
  output  signed[15:0]Q_Ncom,
  output  signed[23:0]I_comcos2,
  output  signed[23:0]Q_comsin2,
  output  signed[7:0]o_Ifir,
  output  signed[7:0]o_Qfir,
  output  [3:0] o_sdout,
  output signed[31:0]o_error_num,
  output signed[31:0]o_total_num  
);
    
    
	// 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)
    ); 
    
    
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_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_012m

  

相關文章