DDS(Direct DIgital Synthesizer)—直接数字频率合成,是一种用于通过单个固定频率的参考时钟信号生成任意波形的频率合成器,被广泛用于测试测量仪表和通信系统中

一、DDS的主要组成部分:

简单DDS系统,最终输出频率只能通过改变参考时钟频率或对PROM重新编程来实现,较为不灵活。

此类DDS系统相对较为灵活
DDS主要有相位累加器、相位调制器、正弦ROM查找表和D/A转换模块四部分组成
相位累加器(一个计数器):是整个DDS的核心,主要完成相位累加,该累加器的值将作为ROM的地址送至正弦ROM查找表中。(无相位调制器时)
相位调制器:接收相位累加器的相位输出,并添加一个相位偏移值,当不需要时,此部分可以删去或者将其设为一个常数。
正弦ROM查找表:主要用于存放需要展示的正弦波的相关数据,输入是ROM的地址值,查找表应该包括一个完整的正弦波周期的响应数字幅度信息。。
D/A转换:将从正弦ROM查找表中送出的数字离散信号转换为模拟信号,输出对应的电压值。
LPF低通平滑滤波器(可有可无):由于经DAC转换器转换的模拟信号难以构成平滑的正弦信号曲线,故而需要低通平滑滤波器。
DDS各组成部分输出样例:

二.基于FPGA的DDS实现
●RTL

●相关模块代码
1.按键输入模块(带有按键消抖功能)

注:按键消抖原理(抖动时间的长短由按键的机械特性决定,一般为5-10ms)

2.DDS核心模块

module dds_core_sin(CLK   ,   // clock, posedge validRST   ,   // reset, high level resetFWEN  ,   // frequency word update enable, high level enableFWIN  ,   // input frequency wordCLKOUT,   // output clockSINOUT);  // sine signal output, 2's complement formatinput           CLK;
input           RST;
input           FWEN;
input [32-1:0]  FWIN;
output[12-1:0]  SINOUT;
output          CLKOUT;parameter FW_WL = 32;   // frequency word word length in bit
parameter RA_WL = 10;   // rom address word length in bit
parameter RD_WL = 12;   // rom data  word word length in bitreg   [FW_WL -1:0]  fwin_R;     // freq word DFF
reg   [FW_WL -1:0]  acc_R;      // phase ACC DFF
reg   [RA_WL -1:0]  addr_R;     // rom address DFF
reg   [RD_WL -1:0]  sinout_R;   // sin wave output DFF
wire  [RD_WL -1:0]  romout_W;   // rom data output wirealways @ (posedge CLK or posedge RST) beginif(RST) beginfwin_R   <= 0;acc_R    <= 0;addr_R   <= 0;sinout_R <= 0;endelse begin// update fwin_R DFFif(FWEN)fwin_R <= #1 FWIN;elsefwin_R <= #1 fwin_R;// update acc_Racc_R <= #1 fwin_R + acc_R;// update addr_R, the acc_R high RA_WL is rom addressaddr_R <= acc_R[FW_WL-1:FW_WL-1-(RA_WL-1)];     // update output DFFsinout_R <= #1 romout_W;end
endDDS_CORE_ROM u_sinrom(.CLK    (CLK      ),  // clock.RA     (addr_R   ),  // read address.RD     (romout_W )); // read dataassign SINOUT = sinout_R;
assign CLKOUT = CLK;endmodule // module dds_core

3.复位其他电路模块(上电自动生成复位信号)

module powerup_reset(CLK       ,   // 时钟   RSTOUT    );  // 生成的复位信号input CLK;
output RSTOUT;
reg RSTOUT;// 时钟周期50ns,经过实验测定,复位持续时间1/10sec,如果时间过短不起作用
// 猜测和FPGA的加载时间以及电路板设计有关
parameter CNTMAX = 5000000 - 1;reg [31:0] counterR;always @ (posedge CLK) beginif(counterR < CNTMAX) begincounterR <= counterR + 1'b1;endelse begincounterR <= CNTMAX;end
endalways @ (counterR) beginif(counterR < CNTMAX) RSTOUT = 1'b1;  // 输出复位有效else RSTOUT = 1'b0;  // 输出复位无效endendmodule

4.生成频率字模块

module generate_freq_word(CLK       ,   // input clockRST       ,   // input reset BUTUP     ,   // input button upwardBUTDOWN   ,   // input button downwardFQWD      ,   // output frequency wordFWEN      );  // output frequency word update enableparameter VAL_FREQ_BASE = 32'h051E_B851;  // 50MHz clock, 1MHz out wave freqword value
parameter VAL_FREQ_MAX  = (VAL_FREQ_BASE * 10);  // 50MHz clock, MAX 10MHz out wave freqword valueinput CLK,RST;
input BUTUP, BUTDOWN;
output [31:0] FQWD;
output FWEN;
// when push button will cause these DFFs 1 clock cycle high level
reg butup_enR, butdown_enR;
reg butup_d1R, butdown_d1R;
reg [31:0] FQWD;
reg FWEN;
/
// pipeline align
// BUTUP        | butup_d1R    |    butup_enR   | FWEN
// BUTDOW       | butdown_d1R  |    butdown_enR | FQWD
/
always @ (posedge CLK or posedge RST) beginif(RST) beginbutup_d1R   <= 1'b0; butdown_d1R <= 1'b0; butup_enR   <= 1'b0;    butdown_enR <= 1'b0; endelse beginbutup_d1R   <= BUTUP    ; butdown_d1R <= BUTDOWN  ;if((~butdown_d1R) && (BUTDOWN))butdown_enR <= 1'b1;elsebutdown_enR <= 1'b0;if((~butup_d1R) && (BUTUP))butup_enR <= 1'b1;elsebutup_enR <= 1'b0;end
end
always @ (posedge CLK or posedge RST) beginif(RST) beginFQWD <= VAL_FREQ_BASE;FWEN <= 1'b1;endelse begin// BUTTON UPif(butup_enR &&(~butdown_enR)) beginif(FQWD == VAL_FREQ_MAX)FQWD <= VAL_FREQ_BASE;elseFQWD <= FQWD + VAL_FREQ_BASE;end// BUTTON DOWNelse if((~butup_enR) &&butdown_enR) beginif(FQWD == VAL_FREQ_BASE)FQWD <= VAL_FREQ_MAX;elseFQWD <= FQWD - VAL_FREQ_BASE;end// no valid button pushelse beginFQWD <= FQWD;   // hold old valueendFWEN <= (butup_enR || butdown_enR);end
endendmodule

5.顶层设计:

module top_sin_wave(CLK       ,   // clock, posedge validBUTUP     ,   // input button freq upward settingBUTDOWN   ,   // input button freq downward setting BUTRST    ,   // reset buttonCLKOUT    ,   // clock outputSINOUT    );  // DDS sine wave out, to DAC
input CLK;
input BUTUP, BUTDOWN, BUTRST;
output CLKOUT;
output[12-1:0]  SINOUT;wire butup_W, butdown_W, butrst_W;
wire butup_no_jitter_W, butdown_no_jitter_W, butrst_no_jitter_W, rst_W;
wire [32-1:0] fqwd_W;
wire fwen_W;
wire dds_clkout_W;
wire [12-1:0]  dds_out_2c_W; // dds output in 2's complement format
// fpga board button is pull-up to VCC
assign butup_W     = ~BUTUP    ;
assign butdown_W   = ~BUTDOWN  ;
assign butrst_W    = ~BUTRST   ;
assign rst_W = butrst_no_jitter_W | pu_rst_W;powerup_reset U_PURST(.CLK       (CLK       ),   // clock   .RSTOUT    (pu_rst_W  ));  // power up resetbutton_in_out U_BUTUP(.CLK      (CLK                ),   // clock.IN       (butup_W            ),   // input button signal.OUT      (butup_no_jitter_W  ));  // output button signalbutton_in_out U_BUTDOWN(.CLK      (CLK                ),   // clock.IN       (butdown_W          ),   // input button signal.OUT      (butdown_no_jitter_W));  // output button signalbutton_in_out U_BUTRST(.CLK      (CLK                ),   // clock.IN       (butrst_W           ),   // input button signal.OUT      (butrst_no_jitter_W ));  // output button signalgenerate_freq_word U_GFQWD(.CLK       (CLK                   ),   // input clock.RST       (rst_W                 ),   // input reset .BUTUP     (butup_no_jitter_W     ),   // input button upward.BUTDOWN   (butdown_no_jitter_W   ),   // input button downward.FQWD      (fqwd_W                ),   // output frequency word.FWEN      (fwen_W                ));  // output frequency word update enabledds_core_sin U_DDS(.CLK      (CLK            ),   // clock, posedge valid.RST      (rst_W          ),   // reset, high level reset.FWEN     (fwen_W         ),   // frequency word update enable, high level enable.FWIN     (fqwd_W         ),   // input frequency word.CLKOUT   (dds_clkout_W   ),   // output clock.SINOUT   (dds_out_2c_W   ));  // sine signal output, 2's complement formatassign SINOUT = dds_out_2c_W;
assign CLKOUT = ~dds_clkout_W;endmodule // module dds_core

6.正弦ROM查找表


●SignalTap仿真验证:

输出波形频率1MHz,一个正弦波周期约采样51个点

输出波形频率3MHz,一个正弦波周期采样(50/3)即约17个点

输出波形频率9MHz,一个正弦波周期采样(17/3)约6个点

输出波形频率10MHz,一个正弦波周期约采样(15/3)即5个点

实验作业:掌握DDS的原理,并且能够回答以下问题

1、如何根据CLK频率和输入频率字来设定输出波形的频率?
设输出正弦波频率为f1,电路系统时钟CLK频率为 fsys,计数器步进增量为 CNT,计数器位宽为n.则


.
2、补码格式能够直接送给DAC么?为什么仿真工具里观察数据有多种选项, 比如unsigned/hex/binary/signed decimal 等等?
无符号数的补码可以直接送入DAC中,但有符号数的补码需要经过转换才可送入DAC中。在有符号数的补码中,正数的补码还是它本身,但负数的补码是符号位保持不变,其余位去反加1得到的。有符号数的补码经最高位取反之后正好是无符号数从小到大的排列,可生成正弦波信号,送入DAC中。
仿真工具里观察数据有许多项,可以根据自己的需求更加直观的观察数据的变化以及验证仿真结果。
3、如何自动生成波表ROM的verilog代码?
由于生成波表ROM的verilog代码很长,极为不便,所以可以通过matlab生成或用C语言编译生成。
4、如何调节ROM的地址空间容量和数据字长?调节这些参数有什么意义和代价。
调节地址容量:可更改RA_WL,RA_WL为ROM地址数据长度。降低地址容量会使能生成的最低频率升高,但ROM所需的存储空间也变少。增加地址容量可以生成更低频率的信号。但增加地址容量如果超过了目前ROM的存储范围,就需要扩充ROM的存储值,就需要更长的代码和更多的存储空间。
调节数据字长:更改RD_WL,RD_WL为ROM输出数据长度。增加字长则会提高精度,但需要更多的端口,如果字长超过了目前ROM的存储字长则需要提高ROM存储值的精度,同时也要求更多的存储空间。缩短字长会降低精度,但也减少了对端口的使用量。
5、如何评价DDS输出波形的质量?
可通过示波器进行观察,也可通过MATLAB进行频谱分析

基于FPGA的DDS实现相关推荐

  1. 基于FPGA实现DDS正弦波发生器

    名言:学无止境. 1 开发环境 操作系统:win7 开发软件:ISE14.7 硬件平台:Xilinx FPGA Spartan6 2 DDS简介 DDS(Direct Digital Synthesi ...

  2. 基于FPGA的DDS信号发生器

    基于FPGA的DDS信号发生器     两个礼拜前就像写这个文档了,但是一直鸽到现在,主要是人摆了.还有个技术上的原因是,我想用串口屏显示波形,在串口调试助手上返回的数据是对的,但是发到串口屏上啥反应 ...

  3. 【FPGA实例】基于FPGA的DDS信号发生器设计

    原文链接来源:www.runoob.com 基于FPGA的DDS信号发生器设计 DDS 原理 ------DDS(直接频率合成) 技术是根据奈奎斯特抽样定理及数字处理技术,把一系列的模拟信号进行不失真 ...

  4. 基于FPGA的DDS算法实现(可调幅值,附ISE联合Modelsim仿真结果)

    基于FPGA的DDS算法实现(附ISE联合Modelsim仿真结果) 声明:这篇博客是在充分参考前人成果的基础上写成的,如有侵权,请联系我作进一步处理.此外,这是我第一次写博客,描述不准确之处敬请指出 ...

  5. CASE_05 基于FPGA的DDS信号发生器

             该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源. 目录 1 简介 2 DDS原理与方案 2.1 方案一:基于CORD ...

  6. 基于FPGA的DDS直接数字频率合成器,频率和相位控制字可配置,在vivado2019.2平台中verilog开发.含testbench

    目录 1.算法概述 2.仿真效果 3.verilog程序 1.算法概述 DDS同DSP(数字信号处理)一样,也是一项关键的数字化技术.DDS是直接数字式频率合成器(Direct Digital Syn ...

  7. 基于FPGA的DDS信号发生器(vivado版本)

    一.设计目标 根据DDS技术原理,在vavido上编写DDS信号源硬件逻辑语言,实现频率.幅度.波形可调的信号源发生器. 频率调节分为11个档位,分别是:1Hz.10Hz.100Hz.500Hz.1k ...

  8. 基于FPGA的DDS在安路TD和EG4A20BG256上遇到的问题及解决方法(四)

    DDS在TD软件实现中遇到的问题 1.使用tang primer的IDE TD时,运行编译报错license(许可证)过期.TD软件需要license来注册软件,否则无法使用开发软件的各种功能. 解决 ...

  9. 【DDS】基于FPGA的DDS研究与设计

    1.软件版本 ISE14.7 2.本算法理论知识 DDS(Direct Digital frequency Synthesis)即直接数字频率合成器,是一种新型的频率合成技术,具有较高的频率分辨率,快 ...

最新文章

  1. gsoap 学习 1-由wsdl文件生成h头文件
  2. amh 4.2 升级php_Centos系统 + AMH4.2面板 PHP升级7.3.5
  3. 小师妹学JVM之:JIT中的PrintAssembly续集
  4. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸
  5. Windows 10下高效工作——快捷键一览
  6. 18.9.22 考试总结
  7. VC++ (MFC)调用 C#生成DLL的方法
  8. android wps页面设置,WPS中设置纸张的方法
  9. cruzer php sandisk 闪迪u盘量产工具_SanDisk Cruzer Micro
  10. Android 各版本gradle下载地址
  11. msm8916 lcd 相关调试点指导
  12. 零基础学java的最佳学习方法
  13. [解决方案]罗技POWERPLAY鼠标垫无法连接G703/G903/G403等鼠标
  14. 堆排序Java实现以及使用场景
  15. 解析聚合新闻数据,并显示到主界面上(简易新闻 二)
  16. 【专题】三分法和牛顿迭代法总结
  17. 原创短视频的美好时代,美拍连出两招加速达人变现
  18. tomcat安装apr
  19. ‘isVNode‘ is not exported by
  20. uniapp调用上一页的方法

热门文章

  1. python 聚类分析 k means
  2. ubuntu10.04.04在windows下采用WUBI安装(nvidia显卡GeForce 405),附带中文输入法安装
  3. TCP-F(orward)ACK:植入快速重传灵魂的强制快速重传
  4. 今年就业形势真的这么差吗????我们公司今天是好拾漏捡宝了
  5. LiveGBS国标GB/T28181流媒体平台接入GB28181设备作为下级支持级联到共享到海康大华宇视等第三方国标平台支持对接政务公安内网国标视频平台
  6. vb计算机 小数前没有0,vb6.0除法运算结果不显示小数点前的0
  7. 智能家居DIY教程连载(1) ——如何正确使用 Sensor 框架
  8. 计算机科学与技术专业调研论文,计算机科学与技术专业调查报告.doc
  9. 阿里妈妈“广告主套利”风控技术分享
  10. python对datetime排序_【python】时间戳、字典列表排序