基于FPGA的2ASK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR

136 阅读5分钟

1.算法仿真效果

vivado2019.2仿真结果如下(完整代码运行后无水印):

 

       本系统在以前写过的ASK调制解调系统的基础上,增加了高斯信道模块,误码率统计模块,可以验证不同SNR情况下的ASK误码情况。

 

设置SNR=20db

 

5973167e3052149cd724b44600678079_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg  

设置SNR=12db

 

1bf453a1fd4daff9d0fab302e51c9a5a_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

设置SNR=8db

 

35c5d4986165fecb0c665f1a91a764cd_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

设置SNR=4db

 

7a29f678555b955bcc701e7998c94c21_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

设置SNR=0db

 

3026123bd8db0310450f683ed556e71a_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

RTL结构如下:

 

aae6bd25f74ab17d1cf565ce5e6c6afe_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.jpg

 

2.算法涉及理论知识概要

         2ASK调制解调是一种数字调制解调技术,它是基于ASK调制的一种数字调制方式。ASK调制是一种模拟调制方式,它是通过改变载波的振幅来传输数字信号。而2ASK调制解调则是将数字信号转换为二进制码,再通过改变载波的振幅来传输数字信号。 2ASK调制的原理是将数字信号转换为二进制码,然后将二进制码与载波信号相乘,得到调制信号。在解调时,将接收到的信号与载波信号相乘,再通过低通滤波器滤波,得到原始的数字信号。       

 

      2ASK是一种数字调制方式,其中“2”代表二进制,即调制信号只有两个幅度水平。在2ASK调制中,数字基带信号控制载波的幅度。当发送二进制“1”时,发送全幅度载波;当发送二进制“0”时,不发送信号,即无载波输出。因此,2ASK信号可以看作是基带脉冲序列与一个全幅度正弦波的乘积。2ASK的调制解调系统结构如下图所示:

 

948865d29adf88147bdc53aa0eb0aa5b_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.png

 

        假设我们的输入二进制序列为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`