当前位置:   article > 正文

基于AD9767高速DAC的DDS信号发生器(Verilog&Vivado)

ad9767


前言

基于AD9767高速DAC的DDS信号发生器


提示:以下是本篇文章正文内容,下面案例可供参考

一、 实现效果

1.做一个双通道的信号发生器
2.简单调整每个通道的频率输出;
3.能够调整每个通道的输出相位;
4.能够输出正弦波,三角波,方波。

二、DDS_AD9767(顶层模块)

代码如下(示例):

`timescale 1ns / 1ps

module DDS_AD9767(
    Clk,
    Reset_n,
    Mode_SelA,
    Mode_SelB,
    DataA,
    ClkA,    //AD9767高速DAC驱动需要
    WRTA,
    DataB,  //AD9767高速DAC驱动需要
    WRTB,   //AD9767高速DAC驱动需要
    ClkB,   //AD9767高速DAC驱动需要
    Key
);
   input Clk;
   input Reset_n;
   input [1:0]Mode_SelA;//实现通道1的波形选择
   input [1:0]Mode_SelB;//实现通道的波形选择
   input [3:0]Key;      //按键实现Fword   Pward切换
   output [13:0]DataA;
   output ClkA;
   output WRTA;
   output [13:0]DataB;
   output ClkB;
   output WRTB;
   
   assign ClkA = Clk;
   assign ClkB = Clk;
   assign WRTA = ClkA;
   assign WRTB = ClkB;  
   
   reg [31:0]FwordA,FwordB;
   reg [11:0]PwordA,PwordB;
 //----------------------------------------------------------------------------
 //双通道例化两次  
   DDS_Module DDS_ModuleA(
        .Clk(Clk),
        .Reset_n(Key_State[2] & Key_State[3]),   //切换时保持统一频率
        .Mode_Sel(Mode_SelA),
        .Fword(FwordA),
        .Pword(PwordA),
        .Data(DataA)
    );
    
   DDS_Module DDS_ModuleB(
        .Clk(Clk),
        .Reset_n(Key_State[2] & Key_State[3]),
        .Mode_Sel(Mode_SelB),
        .Fword(FwordB),
        .Pword(PwordB),
        .Data(DataB)
    ); 
 //----------------------------------------------------------------------------


//----------------------------------------------------------------------------
//四个key按键的按键消抖   
 wire [3:0]Key_Flag;
 wire [3:0]Key_State;
 //按键消抖
 key_filter key_filter0(
    .Clk(Clk),
    .Reset_n(Reset_n),
    .Key(Key[0]),
    .Key_Flag(Key_Flag[0]),
    .Key_State(Key_State[0])
);   
 //按键消抖   
 key_filter key_filter1(
    .Clk(Clk),
    .Reset_n(Reset_n),
    .Key(Key[1]),
    .Key_Flag(Key_Flag[1]),
    .Key_State(Key_State[1])
); 
//按键消抖
 key_filter key_filter2(
    .Clk(Clk),
    .Reset_n(Reset_n),
    .Key(Key[2]),
    .Key_Flag(Key_Flag[2]),
    .Key_State(Key_State[2])
); 
//按键消抖
 key_filter key_filter3(
    .Clk(Clk),
    .Reset_n(Reset_n),
    .Key(Key[3]),
    .Key_Flag(Key_Flag[3]),
    .Key_State(Key_State[3])
);  
//----------------------------------------------------------------------------



//----------------------------------------------------------------------------
//实现按键切换
    reg [2:0]CHA_Fword_Sel;
    reg [2:0]CHB_Fword_Sel;

    reg [2:0]CHA_Pword_Sel;
    reg [2:0]CHB_Pword_Sel;
    
   //按键切换Fword
    always@(posedge Clk or negedge Reset_n)    
    if(!Reset_n)
        CHA_Fword_Sel <= 0;
    else if(Key_Flag[0] &&  (Key_State[0] == 0))
        CHA_Fword_Sel <= CHA_Fword_Sel + 1'd1;
        
    //按键切换Fword    
    always@(posedge Clk or negedge Reset_n)    
    if(!Reset_n)
        CHB_Fword_Sel <= 0;
    else if(Key_Flag[1] &&  (Key_State[1] == 0))
        CHB_Fword_Sel <= CHB_Fword_Sel + 1'd1;    
         
    //按键切换Pword
    always@(posedge Clk or negedge Reset_n)    
    if(!Reset_n)
        CHA_Pword_Sel <= 0;
    else if(Key_Flag[2] &&  (Key_State[2] == 0))
        CHA_Pword_Sel <= CHA_Pword_Sel + 1'd1;
        
     //按键切换Pword   
    always@(posedge Clk or negedge Reset_n)    
    if(!Reset_n)
        CHB_Pword_Sel <= 0;
    else if(Key_Flag[3] &&  (Key_State[3] == 0))
        CHB_Pword_Sel <= CHB_Pword_Sel + 1'd1;

    always@(*)
        case(CHA_Fword_Sel)
            0:FwordA = 86;//2**32 / 50000000;  85.89934592
            1:FwordA = 859;//2**32 / 5000000;
            2:FwordA = 8590;//2**32 / 500000;
            3:FwordA = 85899;//2**32 / 50000;
            4:FwordA = 858993;//2**32 / 5000;
            5:FwordA = 8589935;//2**32 / 500;
            6:FwordA = 85899346;//2**32 / 50;
            7:FwordA = 429496730;//2**32 / 10;
        endcase
        
    always@(*)
        case(CHB_Fword_Sel)
            0:FwordB = 86;//2**32 / 50000000;  85.89934592
            1:FwordB = 859;//2**32 / 5000000;
            2:FwordB = 8590;//2**32 / 500000;
            3:FwordB = 85899;//2**32 / 50000;
            4:FwordB = 858993;//2**32 / 5000;
            5:FwordB = 8589935;//2**32 / 500;
            6:FwordB = 85899346;//2**32 / 50;
            7:FwordB = 429496730;//2**32 / 10;
        endcase  
        
    always@(*)
        case(CHA_Pword_Sel)
            0:PwordA = 0;   //0
            1:PwordA = 341; //30
            2:PwordA = 683; //60
            3:PwordA = 1024;    //90
            4:PwordA = 1707;    //150
            5:PwordA = 2048;    //180
            6:PwordA = 3072;    //270
            7:PwordA = 3641;    //320
        endcase 

    always@(*)
        case(CHB_Pword_Sel)
            0:PwordB = 0;   //0
            1:PwordB = 341; //30
            2:PwordB = 683; //60
            3:PwordB = 1024;    //90
            4:PwordB = 1707;    //150
            5:PwordB = 2048;    //180
            6:PwordB = 3072;    //270
            7:PwordB = 3641;    //320
        endcase    

//----------------------------------------------------------------------------             
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183

三、DDS_Module

代码如下(示例):


module DDS_Module(
    Clk,
    Reset_n,
    Mode_Sel,
    Fword,
    Pword,
    Data
);
    input Clk;
    input Reset_n;
    input [1:0]Mode_Sel;
    input [31:0]Fword;
    input [11:0]Pword;
    output reg[13:0]Data;
    
    //频率控制字同步寄存器
    reg [31:0]Fword_r;
    always@(posedge Clk)
        Fword_r <= Fword;
    
    //相位控制字同步寄存器
    reg [11:0]Pword_r;
    always@(posedge Clk)
        Pword_r <= Pword; 
    
    //相位累加器    
    reg [31:0]Freq_ACC;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        Freq_ACC <= 0;
    else
        Freq_ACC <= Fword_r + Freq_ACC;
 
    //波形数据表地址
    wire [11:0]Rom_Addr;      
    assign Rom_Addr = Freq_ACC[31:20] + Pword_r;


//---------------------------------------------------------------------------
//实现波形选择    
    wire [13:0]Data_sine,Data_square,Data_triangular;
    rom_sine rom_sine(
      .clka(Clk),
      .addra(Rom_Addr),
      .douta(Data_sine)
    );
    
    rom_square rom_square(
      .clka(Clk),
      .addra(Rom_Addr),
      .douta(Data_square)
    ); 
     
    rom_triangular rom_triangular(
      .clka(Clk),
      .addra(Rom_Addr),
      .douta(Data_triangular)
    );  
    
    always@(*)
        case(Mode_Sel)
            0:Data = Data_sine;
            1:Data = Data_square;
            2:Data = Data_triangular;
            3:Data = 8192;
        endcase
//---------------------------------------------------------------------------
        
endmodule


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

四、key_filter

module key_filter(
    Clk,
    Reset_n,
    Key,
//    Key_P_Flag,
//    Key_R_Flag,
    Key_Flag,
    Key_State
);
    input Clk;
    input Reset_n;
    input Key;
//    output reg Key_P_Flag;
//    output reg Key_R_Flag;
    output Key_Flag;
    output reg Key_State;
    
    reg Key_P_Flag;
    reg Key_R_Flag;
    
    assign Key_Flag = Key_P_Flag | Key_R_Flag;
 
 //-----------------------------------------------------------
    //两个寄存器防止亚稳态
    reg [1:0]sync_Key;
    always@(posedge Clk)
        sync_Key <= {sync_Key[0],Key};
    
    reg [1:0] r_Key;
    always@(posedge Clk)
        r_Key <= {r_Key[0],sync_Key[1]};
 //-----------------------------------------------------------       


    wire pedge_key;
    assign pedge_key = r_Key == 2'b01;
    wire nedge_key;
    assign nedge_key = r_Key == 2'b10;
    
    reg [19:0]cnt;
    
    reg [1:0]state;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)begin
        state <= 0;
        Key_R_Flag <= 1'b0;
        Key_P_Flag <= 1'b0;
        cnt <= 0;
        Key_State <= 1;
    end
    else begin
        case(state)
            0:
                begin
                    Key_R_Flag <= 1'b0;
                    if(nedge_key)
                        state <= 1;
                    else
                        state <= 0;
                end
            
            1:
                if((pedge_key)&&(cnt <1000000 -1))begin
                    state <= 0;
                    cnt <= 0;
                end
                else if(cnt >= 1000000 -1)begin
                    state <= 2;
                    cnt <= 0;
                    Key_P_Flag <= 1;
                    Key_State <= 0;
                end
                else begin
                    cnt <= cnt + 1'b1;
                    state <= 1;
                end
                
            2:
                begin
                    Key_P_Flag <= 0;
                    if(pedge_key)
                        state <= 3;
                    else
                        state <= 2;
                 end
                    
            3:
                if((nedge_key)&&(cnt <1000000 -1))begin
                    state <= 2;
                    cnt <= 0;
                end
                else if(cnt >= 1000000 -1)begin
                    state <= 0;
                    cnt <= 0;
                    Key_R_Flag <= 1'b1;
                    Key_State <= 1;
                end
                else begin
                    cnt <= cnt + 1'b1;
                    state <= 3;               
                end
        endcase   
    end

endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106

五、上板演示

1

【附件:】链接:https://pan.baidu.com/s/1dGSAj9wV1GpYPKa4Fl6KuA?pwd=ncix
提取码:ncix

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/974296
推荐阅读
  

闽ICP备14008679号