FPGA-DDS原理及实现

DDS(Direct Digital Synthesizer)即数字合成器,是一种新型的频率合成技术,具有相对带宽大,频率转换时间短、分辨率高和相位连续性好等优点。较容易实现频率、相位以及幅度的数控调制,广泛应用于通信领域。

  

相位累加器是由N位加法器与N位寄存器构成,每个时钟周期的上升沿,加法器就将频率控制字与累加寄存器输出的相位数据相加,相加的结果又反馈至累加器的数据输入端,以使加法器在下一个时钟脉冲作用下继续与频率控制字相加。这样,相位累加器在时钟的作用下,不断对频率控制字进行线性相位累加。即在每一个时钟脉冲输入时,相位累加器便把频率控制字累加一次。

相位累加器的输出数据就是合成信号的相位。相位累加器的溢出频率,就是相位累加器的输出数据,作为波形存储器的相位采样地址,这样就可以把存储在波形存储器里的波形采样值经查表找出,完成相位到幅度的转换。波形储存器送到D/A转换器,再由D/A转换器将数字信号转换成模拟信号输出。

分析建模

然后我们来编写DDS逻辑程序

首先先创建ROM IP核  分别存放正弦波 方波 三角波数据

如下是正弦波的创建步骤:

三角波,方波创建步骤如以上正弦波类似,

然后编写程序

module DDS_AD9767(
    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 [31: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 <= Freq_ACC + Fword_r;
    
    //波形数据变地址
    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),    // input wire clka
      .addra(Rom_Addr),  // input wire [11 : 0] addra
      .douta(Data_sine)  // output wire [13 : 0] douta
    );
    rom_square rom_square (
      .clka(Clk),    // input wire clka
      .addra(Rom_Addr),  // input wire [11 : 0] addra
      .douta(Data_square)  // output wire [13 : 0] douta
    );        
    rom_triangular rom_triangular (
      .clka(Clk),    // input wire clka
      .addra(Rom_Addr),  // input wire [11 : 0] addra
      .douta(Data_triangular)  // output wire [13 : 0] douta
    );  
    
    always@(*)
        case(Mode_Sel)
            0:Data = Data_sine;
            1:Data = Data_square;
            2:Data = Data_triangular;
            3:Data = 8192;     
        endcase
endmodule

编写测试文件

`timescale 1ns / 1ps

module DDS_AD9767_tb;
    reg Clk;
    reg Reset_n;
    reg [1:0]Mode_SelA,Mode_SelB;
    reg [31:0]FwordA,FwordB;
    reg [11:0]PwordA,PwordB;
    wire  [13:0]DataA,DataB;
    DDS_AD9767 DDS_AD9767A(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Mode_Sel(Mode_SelA),
        .Fword(FwordA),
        .Pword(PwordA),
        .Data(DataA)
        );
    DDS_AD9767 DDS_AD9767B(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Mode_Sel(Mode_SelB),
        .Fword(FwordB),
        .Pword(PwordB),
        .Data(DataB)
        );  
    initial Clk = 1;
    always #10 Clk = ~Clk;
    
    initial begin
        Reset_n = 0;
        FwordA = 65536;
        PwordA = 0;
        FwordB = 65536;
        PwordB = 1024;
        Mode_SelA = 2'B00;
        Mode_SelB = 2'B00;
        #201;
        Reset_n = 1;
        #5000000;
        FwordA = 65536*1024;
        PwordA = 0;
        FwordB = 65536*1024;
        PwordB = 2048;      
        #1000000;
        $stop;  
    end   
    
    
endmodule

仿真波形如下:

将仿真波形调为模拟量输出

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值