zoukankan      html  css  js  c++  java
  • 基于FPGA的通信系统实验

    伪随机信号发生器

    1、伪随机信号发生器原理

        伪随机信号发生器又叫PN序列发生器或者是m序列发生器。m序列是一种线性反馈寄存器序列,m序列的产生可以利用r级寄存器产生长度为2^r-1的m序列,该实验中采用3级寄存器产生7序列发生器。其原理框图如下:(实验中反馈的信号采用异或进行反馈)

    仿真波形:

    2、实验代码

    module m_ser(

    clk,

    reset_n,

    load,

    m_ser_out

    );

    input clk;

    input reset_n;

    input load;

    output m_ser_out;

    wire clk;

    wire reset_n;

    wire load;

    reg m_ser_out;

    reg[2:0] m_code;

    always@(posedge clk ornegedge reset_n)

    begin

    if(!reset_n)

    begin

    m_code<=3'b000;

    m_ser_out<=1'b0;

    end

    else

    if(load)

    begin

    m_code<=3'b001;//置数初始化

    m_ser_out<=m_code[2];

    end

    else

    begin

    m_code[2:1]<=m_code[1:0];

    m_code[0]<=m_code[2]^ m_code[0];//20进行异或然后放到0

    m_ser_out<=m_code[2];

    end

    end

    endmodule

    2ASK调制

    1、原理

        在通信系统中,有时经常需要进行二进制数字调制。2ASK即是二进制幅值键控,2ASK的调制原理就是:基带信号为"0"时,输出保持为"0",基带信号为"1"时,输出一个特定频率的信号,如下图所示:

     

     

    原理图如下:

    2、实验仿真

        通过仿真结果可以看出,当data_in输入为高时,调制输出一定频率的信号,输入为低时,调制输出低电平。

    3、实验代码

    module ask(

    clk,

    reset_n,

    data_in,

    ask_code_out

    );

    input clk;

    input reset_n;

    input data_in;

    output ask_code_out;

    wire clk;

    wire reset_n;

    wire data_in;

    reg[2:0]clk_cnt;

    reg clk_div;

    always@(posedge clk ornegedge reset_n)//产生分频信号

    begin

    if(!reset_n)

    begin

    clk_cnt<=3'd0;

    clk_div<=1'b0;

    end

    else

    if(clk_cnt==3'd1)

    begin

    clk_div<=~clk_div;

    clk_cnt<=3'd0;

    end

    else

    clk_cnt<=clk_cnt +1'b1;

    end

    assign ask_code_out=(data_in)? clk_div :1'b0;

    endmodule

    2FSK调制

    1、原理

        2FSK的调制原理是当基带信号为"0"时,输出一个固定频率为f1的信号,当基带信号为"1"时,输出一个固定频率为f2的信号。如下图所示:

    原理图如下:

     

    2、实验仿真

    3、实验代码

    module fsk_code(

    clk,

    m_ser_code_in,

    fsk_code_sin_out

    );

    input clk;

    input m_ser_code_in;

    output fsk_code_sin_out;

    wire clk;

    wire m_ser_code_in;

    reg[2:0]cnt;

    wire f1;

    reg f2;

    always@(posedge clk )

    begin

    if(cnt==3'd2)

    begin

    cnt<=3'd0;

    f2<=~f2;

    end

    else

    cnt<=cnt+1'b1;

    end

    assign f1=clk;

    assign fsk_code_sin_out=(m_ser_code_in)? f1:f2;

    endmodule

    2PSK调制

    1、2PSK调制原理

        在PSK调制时,载波的相位随调制信号状态不同而改变。如果两个频率相同的载波同时开始振荡,这两个频率同时达到正最大值,同时达到零值,同时达到负最大值,此时它们就处于"同相"状态;如果一个达到正最大值时,另一个达到负最大值,则称为"反相"。一般把信号振荡一次(一周)作为360度。如果一个波比另一个波相差半个周期,我们说两个波的相位差180度,也就是反相。当传输数字信号时,"1"码控制发0度相位,"0"码控制发180度相位。调制原理如下:

    2、实验原理图说明

        当伪随机信号发生器输出"1"时,PSK调制输出0度相位的正弦波形;当伪随机信号发生器输出"0"时,PSK调制输出180度相位的正弦波形;在这里,不详细说明"伪随机信号发生器"和"DDS信号发生器的原理",具体可以参考相应的章节。

    3、仿真效果

        采用ModelSim进行仿真:

    4、实验代码

    //"1"码控制发0度相位,"0"码控制发180度相位

    module psk_code(

    clk,

    m_ser_code_in,

    dds_sin_data_in2,//10k正弦波

    dds_sin_data_in3,//10k正弦波,相位相差180

    psk_code_sin_out//

    );

    input clk;

    input m_ser_code_in;

    input[9:0]dds_sin_data_in2;

    input[9:0]dds_sin_data_in3;

    output[9:0]psk_code_sin_out;

    wire clk;

    wire m_ser_code_in;

    wire[9:0]dds_sin_data_in2;

    wire[9:0]dds_sin_data_in3;

    assign psk_code_sin_out=(m_ser_code_in)? dds_sin_data_in2:dds_sin_data_in3;

    endmodule

    2DPSK调制

    1、2DPSK原理

        在2PSK中,是利用载波相位的绝对数值来传送数字信息,因而称为绝对调相;2DPSK即是二进制差分相移键控,不利用载波相位传送数字信息,而是利用前后码元的相对相位变化传送数字信息。

        实现相对调相的常用方法有:先对数字基带信号进行差分编码,将绝对编码转换成差分编码,然后再进行绝对调相。

        将数字基带信号由绝对编码转成差分编码的方法为:将前一个输出码元和当前的输入码元进行异或,这样就可以产生相对码。

    其原理图为:

    2、实验设计

        将伪随机信号发生器产生的m序列进行差分编码,再将相对码进行2DPSK调制,当出现"0"码则输出0度相位正弦波,"1"码控制发180度相位正弦波。

    3、实验仿真

    将绝对编码转为相对编码

    2DPSK调制:

    4、实验代码

    //"0"码控制发0度相位,"1"码控制发180度相位

    module dpsk_code(

    clk,

    reset_n,//

    m_ser_code_in,//PN序列输入

    dpsk_code_out,//dpsk调制输出

    dds_sin_data_in2,//10k正弦波

    dds_sin_data_in3,//10k正弦波,相位相差180

    dpsk_code_sin_out

    );

    input clk;

    input reset_n;

    input m_ser_code_in;

    input[9:0] dds_sin_data_in2;

    input[9:0] dds_sin_data_in3;

    output dpsk_code_out;

    output[9:0]dpsk_code_sin_out;

    wire clk;

    wire reset_n;

    wire m_ser_code_in;

    wire[9:0] dds_sin_data_in2;

    wire[9:0] dds_sin_data_in3;

    reg dpsk_code_reg;

    //差分编码

    always@(posedge clk ornegedge reset_n)

    begin

    if(!reset_n)

    begin

    dpsk_code_reg<=1'b0;

    end

    else

    dpsk_code_reg<=dpsk_code_reg ^ m_ser_code_in;//前一个码元与输入的码元进行异或

    end

    assign dpsk_code_out=dpsk_code_reg;

    assign dpsk_code_sin_out=(dpsk_code_reg)? dds_sin_data_in3 : dds_sin_data_in2;

    endmodule

    大西瓜FPGA-->https://daxiguafpga.taobao.com

    博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!

    每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号“科乎”。

  • 相关阅读:
    asp.net :使用jquery 的ajax +WebService+json 实现无刷新去后台值
    如何清理数据库缓存
    如何在虚拟机中Linux+Oracle10gRAC安装
    ORA01031 权限不足存储过程中DBA 角色用户无法执行DDL
    如何查看存储过程执行计划
    如何查看执行计划
    如何使用tkprof
    C#位运算讲解与示例[转]
    C#中Invalidate() 方法
    如何创建强命名程序集, 如何查看强命名程序集的PublicKeyToken
  • 原文地址:https://www.cnblogs.com/logic3/p/5303583.html
Copyright © 2011-2022 走看看