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

我爱C编程發表於2024-09-18

1.演算法模擬效果

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

本系統在以前寫過的ASK調製解調系統的基礎上,增加了高斯通道模組,誤位元速率統計模組,可以驗證不同SNR情況下的ASK誤碼情況。

設定SNR=20db

設定SNR=12db

設定SNR=8db

設定SNR=4db

設定SNR=0db

RTL結構如下:

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

2ASK調製解調是一種數字調製解調技術,它是基於ASK調製的一種數字調製方式。ASK調製是一種模擬調製方式,它是透過改變載波的振幅來傳輸數字訊號。而2ASK調製解調則是將數字訊號轉換為二進位制碼,再透過改變載波的振幅來傳輸數字訊號。 2ASK調製的原理是將數字訊號轉換為二進位制碼,然後將二進位制碼與載波訊號相乘,得到調製訊號。在解調時,將接收到的訊號與載波訊號相乘,再透過低通濾波器濾波,得到原始的數字訊號。

2ASK是一種數字調製方式,其中“2”代表二進位制,即調製訊號只有兩個幅度水平。在2ASK調製中,數字基帶訊號控制載波的幅度。當傳送二進位制“1”時,傳送全幅度載波;當傳送二進位制“0”時,不傳送訊號,即無載波輸出。因此,2ASK訊號可以看作是基帶脈衝序列與一個全幅度正弦波的乘積。2ASK的調製解調系統結構如下圖所示:

假設我們的輸入二進位制序列為an,那麼2ASK的調製過程可以用以下數學公式表示:

e2ASK(t) = Σan g(t - nTs) cos(ωct)

其中,g(t)是基帶脈衝形狀,Ts是基帶脈衝間隔,ωc是載波的角頻率。解調過程則是對接收到的訊號進行包絡檢波,恢復出原始的二進位制序列。

FPGA上實現2ASK調製解調系統主要分為以下幾個步驟:

系統設計:首先,我們需要根據2ASK調製解調的原理設計出系統的整體架構,包括調製器、通道模擬器和解調器等主要部分。

Verilog編碼:然後,我們使用Verilog硬體描述語言對系統各個部分進行編碼。例如,我們可以建立一個調製器模組,它接收二進位制輸入,根據2ASK調製原理生成相應的調製訊號。同樣,我們也需要建立一個解調器模組,它接收調製訊號,透過包絡檢波恢復出原始的二進位制序列。

模擬測試:編碼完成後,我們需要透過模擬測試驗證我們的設計是否正確。我們可以使用一些測試工具,如ModelSim,對我們的設計進行模擬。透過觀察模擬結果,我們可以檢查我們的設計是否滿足預期。

FPGA實現:最後,我們將透過模擬測試的設計下載到FPGA上進行實現。這通常需要使用特定的FPGA開發工具,如Xilinx Vivado。在這個步驟中,我們需要考慮FPGA的資源限制和效能最佳化等問題。

FPGA實現過程中,需要注意的是,由於FPGA是硬體實現,所以設計需要考慮實時性和並行性。此外,對於調製和解調過程中的一些非線性操作,可能需要利用FPGA的查詢表(LUT)等資源進行最佳化。

3.Verilog核心程式

`timescale 1ns / 1ps
//
 
 
module test_ASK2;
 
reg i_clk;
reg i_rst;
reg[1:0]i_bits;
reg signed[7:0]i_SNR;
wire signed[15:0]o_2ask;
wire signed[15:0]o_2ask_Rn;
wire signed[31:0]o_de_2askf;
wire [1:0]o_bits;
wire signed[31:0]o_error_num;
wire signed[31:0]o_total_num; 
 
 
 
ASK2 uut(
.i_clk(i_clk),
.i_rst(i_rst),
.i_bits({~i_bits,1'b1}),
.i_SNR(i_SNR),
.o_2ask(o_2ask),
.o_2ask_Rn(o_2ask_Rn),
.o_de_2ask(),
.o_de_2askf(o_de_2askf),
.o_bits(o_bits),
.o_error_num(o_error_num),
.o_total_num(o_total_num)
);
 
initial
begin
    i_clk = 1'b1;
    i_rst = 1'b1;
    i_SNR=20;//這個地方可以設定訊雜比,數值大小從0~50,
    #1000
    i_rst = 1'b0;
end
initial
begin
    i_bits= 1'b0;
    #1024
    i_bits= 1'b1;
    #256
    i_bits= 1'b0;
    #512
    i_bits= 1'b1;
    #512
    i_bits= 1'b1;
    #512
    i_bits= 1'b1;
    #1024
    i_bits= 1'b0;
    #512
    i_bits= 1'b0;
    #256
    i_bits= 1'b1;
    #128
    i_bits= 1'b1;
    #128
    i_bits= 1'b0;
    repeat(10000)
    begin
    #256
    i_bits= 1'b0;
    #2048
    i_bits= 1'b1;
    #2048
    i_bits= 1'b0;
    #2048
    i_bits= 1'b1;
    #2048
    i_bits= 1'b1;
    #2048
    i_bits= 1'b0;
    #1024
    i_bits= 1'b1;
    #1024
    i_bits= 1'b0;
    #1024
    i_bits= 1'b1;
    #512
    i_bits= 1'b1;
    #512
    i_bits= 1'b0;
    #512
    i_bits= 1'b1;
    #256
    i_bits= 1'b1;
    #256
    i_bits= 1'b0;
    #512
    i_bits= 1'b1;
    #256
    i_bits= 1'b0;
    #128
    i_bits= 1'b0;
    
    #128
    i_bits= 1'b0;
    #128
    i_bits= 1'b1;
    #1024
    i_bits= 1'b0;
    #512
    i_bits= 1'b0;
    #128
    i_bits= 1'b1;
    #256
    i_bits= 1'b1;
    #128
    i_bits= 1'b1;
    #256
    i_bits= 1'b0;
    end
end
 
 
 
always #1 i_clk=~i_clk;
 
endmodule
0sj_004m

  

相關文章