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

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例化

2.1 parameter selection 选择system parameters

在这里插入图片描述

2.1.1 参数设置

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

2.1.2 源码

程序结构
在这里插入图片描述

2.1.2.1 顶层文件

`timescale 1ns / 1ps


module top(
    input           sys_clk         ,//系统时钟
    input           rst_n           ,//系统复位
    input  [1:0]    key_PINC         // 按键控制频率选择
    );
 

 //频率设置模块
wire  [23:0]   Fword ;  //频率字

Fword_set Fword_set_inst(
        //input
        .clk        (sys_clk            ),
        .rst_n      (rst_n              ),
        .key_PINC   (key_PINC           ),
        //output
        .Fword      (Fword              )
        );



//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
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  (Fword                  ),    // input wire [23: 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

2.1.2.2 频率控制模块
`timescale 1ns / 1ps
//
// 通过按键来选择对应的频率控制字,进而选择对应的信号频率
//


module Fword_set(
    input               clk         ,
    input               rst_n       ,
    input  [1:0]        key_PINC    ,
    
    output reg [23:0]   Fword
    );
    
    
//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:  Fword <= 'h28f5;     //1Mhz  10485  每次相位增加的值  deta_theta
        1:  Fword <= 'h51eb;     //2Mhz  20971
        2:  Fword <= 'ha3d7;     //4Mhz  41943
        3:  Fword <= 'h19999;    //10Mhz  104857
    endcase
end

 
endmodule

2.1.2.3 testbench文件
`timescale 1ns / 1ps


module sim_top;

    reg         sys_clk;
    reg         rst_n;
    reg [1:0]   key_PINC; 


    //例化源文件
    top top_inst(
    .sys_clk      (sys_clk      ),
    .rst_n        (rst_n        ),
    .key_PINC     (key_PINC     )
        );
        
             
    initial
        begin
            //初始化输入
            sys_clk=0;
            rst_n=0;
            key_PINC=2'd0;
  
            
            #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

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



endmodule


2.1.3 仿真结果

在这里插入图片描述
在这里插入图片描述
可以看出,不同频率的波形的相位是连续的

2.2 parameter selection 选择hardware parameters

在这里插入图片描述
parameter selection 选择hardware parameters后,相位位宽phase width和输出位宽output width是可控的。

2.2.1 参数设置

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

2.2.2 源代码

2.2.2.1 结构图

在这里插入图片描述

2.2.2.2 顶层文件
`timescale 1ns / 1ps
//  频率控制字fre_ctrl_word是如何确定的?
// 根据IP核的summery, phase width=32bits   Frequency per channel=125MHz
// 输出频率的计算公式:f_out(3M)=f_clk*deta_theta/(2^B)   
// 输出频率字的计算公式:deta_theta=f_out*(2^B)/f_clk    

module top(
    input           sys_clk         ,//系统时钟
    input           rst_n           //系统复位
    );
 


//output
wire [31:0]  m_axis_data_tdata     ;


 //DDS
dds_sin dds_sin_inst (
  .aclk(sys_clk),                                  // input wire aclk
  .s_axis_config_tvalid(1'b1 ),  // input wire s_axis_config_tvalid
  .s_axis_config_tdata( 32'h06594AF5),    // input wire [31 : 0] s_axis_config_tdata  3M
 
  .m_axis_data_tvalid(),      // output wire m_axis_data_tvalid
  .m_axis_data_tdata(m_axis_data_tdata),        // output wire [31 : 0] m_axis_data_tdata
  .m_axis_phase_tvalid(),    // output wire m_axis_phase_tvalid
  .m_axis_phase_tdata()      // output wire [31 : 0] m_axis_phase_tdata
);

    
    
    
endmodule
2.2.2.3 仿真文件
`timescale 1ns / 1ps


module sim_top;

    reg         sys_clk;
    reg         rst_n;


    //例化源文件
    top top_inst(
    .sys_clk      (sys_clk      ),
    .rst_n        (rst_n        )
        );
        
             
    initial
        begin
            //初始化输入
            sys_clk=0;
            rst_n=0;
       
            #20
            rst_n=1;

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



endmodule

2.2.3 结果

在这里插入图片描述
1)信号频率为3M
2)高16位为实部,低16位为虚部

  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DDS(Direct Digital Synthesis)是一种数字直接合成技术,通过对数字量进行运算,可以实现精确控制和生成各种波形信号。LFM(Linear Frequency Modulation)信号是一种频率线性变化的信号,在雷达、通信等领域有广泛应用。 DDS生成LFM信号的关键是对频率进行线性变化。具体步骤如下: 首先,需要确定LFM信号的起始频率和终止频率以及变化的时间间隔。假设起始频率为f1,终止频率为f2,时间间隔为T。 然后,通过DDS的相位累加器对相位进行控制。相位累加器可以根据给定的频率和时间间隔,计算出每个时刻的相位值。在LFM信号中,相位值随时间线性变化。 接下来,通过DDS的频率控制器对频率进行控制。频率控制器根据相位累加器计算出的相位值,生成相应的频率值。在LFM信号中,频率值随时间线性变化,从起始频率f1到终止频率f2。 最后,通过DDS的数模转换器将生成的数字信号转换为模拟信号。转换后的模拟信号即为LFM信号。 需要注意的是,在生成LFM信号时,DDS的时钟频率要足够高,以保证对频率的精确控制。另外,DDS还可以通过添加窗函数对信号进行平滑处理,以减少频率变化时的幅度跳变。 总结起来,DDS生成LFM信号的过程可以分为确定起始频率和终止频率、相位累加器控制相位、频率控制器控制频率和数模转换器转换为模拟信号等步骤。利用DDS的高精度和可控性,可以在各种应用中生成需要的LFM信号

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值