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