测试测量
返回首页

基于FPGA的DDS 信号发生器(三)

2022-07-01 来源:csdn

1 DDS原理

1.1 书上的解释

DDS(Direct Digital Synthesizer)技术是一种全新的频率合成方法,是从相位概念出发直接合成所需波形的一种频率合成技术,通过控制相位的变化速度,直接产生各种不同频率、不同波形信号的一种频率合成方法。

在这里插入图片描述

系统的核心是相位累加器,其内容会在每个时钟周期(system clock)更新。相位累加器每次更新时,存储在Δ相位寄存器中的数字字M就会累加至相位寄存器中的数字。假设Δ相位寄存器中的数字为00…01(即M=1),相位累加器中的初始内容为00…00。相位累加器每个时钟周期都会按00…01(M=1)更新。如果累加器为32位宽,则在相位累加器返回至00…00前需要2^32(超过40亿)个时钟周期,周期会不断重复。


相位累加器的截断输出用作正弦(或余弦)查找表的地址。查找表中的每个地址均对应正弦

波的从0°到360°的一个相位点。查找表包括一个完整正弦波周期的相应数字幅度信息。

(实际上,只需要90°的数据,因为两个MSB中包含了正交数据)。因此,查找表可将相位

累加器的相位信息映射至数字幅度字,进而驱动DAC。图3用图形化的“相位轮”显示了这

一情况。


考虑n = 32,M = 1的情况。相位累加器会逐步执行2^ 32 (2^n/M)个可能的输出中的每一个,直至溢出并重新开始。相应的输出正弦波频率等于输入时钟频率 2 ^ 32分频。若M=2,相位累加器寄存器就会以两倍的速度“滚动”计算,输出频率也会增加一倍。以上内容可总结如下:

在这里插入图片描述

1.2 自己的理解

DDS系统主要由相位累加器、波形存储器、数模(D/A)转换器和低通滤波器等四个大的结构组成,其结构框图如下图所示。

在这里插入图片描述参考时钟:

图中,参考频率f_clk为固定值,一般我们选择系统时钟(system clock),这里设置的是100MHz。

频率控制字:

用来调整输出信号的频率。如何根据参考频率得到输出频率,DDS IP的官方文档给出了相应公式。

在这里插入图片描述
在这里插入图片描述

相位控制字:

在这里插入图片描述

相位累加器:

由N位加法器与N位累加寄存器构成,它根据频率控制字k,完成相位值的累加,并将此累加值输入到波形存储器中。

波形存储器:

将相位累积器的值作为当地址,查找与相位值对应的信号数据,输出到D/A转换器。

D/A转换器:

将波形存储器输出的数字量转换为与之对应的模拟量。

低通滤波器:

由于D/A转换器存在量化误差,输出波形中存在混叠,需要在输出端使用低通滤波器进行滤波,提高信号的输出性能。


2 DDS IP的参数设置

在这里插入图片描述

需要注意的是,上面的频率分辨率(frequency resolution)的值是算出来的,这个值必须和summer的频率分辨率保持一致。100M/(2^20)=95.36743

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3 源码

程序结构

在这里插入图片描述

3.1 顶层文件

`timescale 1ns / 1ps



module top(

    input           sys_clk         ,// 系统时钟

    input           rst_n           ,// 系统复位

    input  [1:0]    key_PINC        ,// 频率控制字对应的按键

    input  [1:0]    key_POFF         // 相位控制字对应的按键

    );

 

 


 //-----------频率控制字模块

wire  [23:0]   PINC ;  //频率字

Fword_set Fword_set_inst(

        //input

        .clk        (sys_clk            ),

        .rst_n      (rst_n              ),

        .key_PINC   (key_PINC           ),

        //output

        .PINC       (PINC               )

        );




 //-----------相位控制字模块

 wire  [23:0]   POFF ;  //相位字

POFF_set POFF_set_inst(

    //input

    .clk        (sys_clk   )    ,

    .rst_n      (rst_n     )    ,

    .key_POFF   (key_POFF  )    ,

    //output

    .POFF       (POFF      )

    );






 //-------------DDS模块

//input

wire [0:0]   fre_ctrl_word_en  ;    


//output

wire [0:0]   m_axis_data_tvalid    ;

wire [47:0]  m_axis_data_tdata     ;

wire [0:0]   m_axis_phase_tvalid   ;

wire [23:0]  m_axis_phase_tdata    ;


assign fre_ctrl_word_en=1'b1;


dds_sin dds_sin_inst (

  .aclk                 (sys_clk                ),    // input wire aclk

  .s_axis_config_tvalid (fre_ctrl_word_en       ),    // input wire s_axis_config_tvalid

  .s_axis_config_tdata  ({POFF,PINC}           ),    // input wire [47 : 0] s_axis_config_tdata

 

  .m_axis_data_tvalid   (m_axis_data_tvalid     ),    // output wire m_axis_data_tvalid

  .m_axis_data_tdata    (m_axis_data_tdata      ),    // output wire [47 : 0] m_axis_data_tdata

  .m_axis_phase_tvalid  (m_axis_phase_tvalid    ),    // output wire m_axis_phase_tvalid

  .m_axis_phase_tdata   (m_axis_phase_tdata     )     // output wire [23 : 0] m_axis_phase_tdata

); 

    

endmodule


3.2 频率控制字模块

`timescale 1ns / 1ps

//

// 通过按键来选择对应的频率控制字,进而选择对应的信号频率

//



module Fword_set(

    input               clk         ,

    input               rst_n       ,

    input  [1:0]        key_PINC    ,

    

    output reg [23:0]   PINC

    );

    

    

//always@(posedge clk or negedge rst_n)

//begin

//    if(!rst_n)

//        key_sel <= 4'd0;

//    else

//        key_sel <= key_sel;

//end

   

   

//  The output frequency(f_out ) , of the DDS waveform is a function of the system clock frequency(f_clk ) .

//  the phase width, that is, number of bits (B )  in the phase accumulator 

//  and the phase increment value (deta_theta) . 

//  The output frequency in Hertz is defined by:f_out=f_clk*deta_theta/(2^B)

//  fre_ctrl_word是如何确定的?

// 根据IP核的summery, phase width=20bits   Frequency per channel=100MHz

// 输出频率的计算公式f_out=f_clk*deta_theta/(2^B)=100M* 104857/(2^20 )= 10M             

always@(*)

begin

    case(key_PINC)

        0:  PINC <= 'h28f5;     //1Mhz  10485  每次相位增加的值  deta_theta

        1:  PINC <= 'h51eb;     //2Mhz  20971

        2:  PINC <= 'ha3d7;     //4Mhz  41943

        3:  PINC <= 'h19999;    //10Mhz  104857

    endcase

end


 

endmodule


3.3 相位控制字模块

`timescale 1ns / 1ps

//

// 通过按键来选择对应的相位控制字,进而选择对应的信号初始相位

/



module POFF_set(

    input               clk         ,

    input               rst_n       ,

    input  [1:0]        key_POFF    ,

    

    output [23:0]       POFF

    );

    

    

//always@(posedge clk or negedge rst_n)

//begin

//    if(!rst_n)

//        key_sel <= 4'd0;

//    else

//        key_sel <= key_sel;

//end


// 根据IP核的summery, phase_width=20bits   Frequency per channel=100MHz

// 输出相位的计算公式:POFF=phase*phase_modulus/360

// phase:想要输出的相位,输入0~360即可

// phase_modulus:相位系数为2^phase_width-1=2^20-1,

// phase_width即相位位宽,在生成IP的summary可以查看

reg  [8:0]   phase;    //0-360   

   

always@(*)

begin

    case(key_POFF)

        0:  phase <= 'h0;         //0

        1:  phase <= 'h5a;        //90

        2:  phase <= 'hb4;        //180

        3:  phase <= 'h10e;       //270

    endcase

end


assign POFF=phase*1048575/360;

 

endmodule


3.4 testbench文件

`timescale 1ns / 1ps



module sim_top;


    reg         sys_clk ;

    reg         rst_n   ;

    reg [1:0]   key_PINC; 

    reg [1:0]   key_POFF; 


    //例化源文件

    top top_inst(

       .sys_clk      (sys_clk      ),

       .rst_n        (rst_n        ),

       .key_PINC     (key_PINC     ),

       .key_POFF     (key_POFF     )

        );

        

             

    initial

        begin

            //初始化

            sys_clk=0;

            rst_n=0;

            key_PINC=2'd0;

            key_POFF=2'd0;  //30

            

            

            

            #100

            rst_n=1;

            key_PINC=0;  //1Mhz  10485  每次相位增加的值  deta_theta

            #4000

            key_PINC=1;  //2Mhz  20971

            #4000

            key_PINC=2;  //4Mhz  41943

            #4000

            key_PINC=3;   //10Mhz  104857

            

            #4000

            key_POFF=1;  //60

            #4000

            key_POFF=2;  //90

            #4000

            key_POFF=3;   //180

        end

        

        

        // create clock;

        always #5 sys_clk=~sys_clk;//每次间隔5ns,取一次反,也就是周期为10ns,所以频率为100MHz


endmodule


4 结果

在这里插入图片描述
在这里插入图片描述

进入测试测量查看更多内容>>
相关视频
  • LABVIEW数据采集随书视频

  • 微机电系统技术

  • 周公系列讲座——示波器讲解

  • 了解传感器融合和追踪

  • 电子设计竞赛中测控类题目应用对策

  • 电子测量与智能仪器(浙江大学)

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 用数字电路CD4069制作的万能遥控轻触开关

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章