DDS信号的发生器(验证篇)——FPGA学习笔记8

前言:第一部分详细讲解DDS核心框图,还请读者深入阅读第一部分,以便理解DDS核心思想

三刷小梅哥视频总结!

小梅哥icon-default.png?t=N7T8https://www.corecourse.com/lander

一、DDS简介

        DDS(Direct Digital Synthesizer)即数字合成器,是一种新型的频率合成技术,具有低成本、低功耗、高分辨率、频率转换时间短、相位连续性好等优点,对数字信号处理及其硬件实现有着很重要的作用。 DDS的基本结构主要由相位累加器、相位调制器、波形数据表 ROM、 D/A 转换器等四大结构组成,其中较多设计还会在数模转换器之后增加一个低通滤波器(LPF)。 DDS 基本结构图如下图所示。

        由上图可以看出, DDS 主要由相位累加器、相位调制器、波形数据表以及 D/A 转换器构成。其中相位累加器由 N 位加法器与 N 位寄存器构成。每来一个时钟,加法器就将频率控制字与累加寄存器输出的相位数据相加,相加的结果又反馈至累加寄存器的数据输入端,以使加法器在下一个时钟脉冲的作用下继续与频率控制字相加。这样,相位累加器在时钟的作用下,不断对频率控制字进行线性相位累加。即在每一个时钟脉冲输入时,相位累加器便把频率控制字累加一次。当相位累加器累加满量时就会产生一次溢出,完成一个周期的动作。相位累加器输出的数据就是合成信号的相位。相位累加器的溢出频率,就是 DDS 输出的信号频率。

        通过改变相位控制字 P_WORD 可以控制输出信号的相位参数。令相位加法器的字长为 M,当相位控制字由 0 跃变为 P_WORD 时,波形存储器(ROM)的输入为相位累加器的输出与相位控制字 P_WORD 之和,因而其输出的幅度编码相位会增加 P_WORD/2M,从而使输出的信号产生相移。

        用相位调制器输出的数据,作为波形存储器的相位采样地址,这样就可以把存储在波形存储器里的波形采样值经查表找出,完后相位到幅度的转换。 N 位的寻址 ROM 相当于把 0° -360°的正弦信号离散成具有 2N个样值的序列。若波形存储器中有 D 位数据位,则 2N 个样值的幅值以 D 位二进制数值固化在波形存储器当中。按照地址的不同可以输出相应相位的正弦信号幅值。相位—幅度变换原理图如下图所示:

        数模转换器(D/A)的作用是把合成的正弦波数字量转化为模拟量。正弦幅度量化序列经数模转换器转换后变成了包络为正弦波的阶梯波。频率合成器对数模转换器的分辨率有一定的要求,其分辨率越高,合成的正弦波台阶数就越多,输出的波形精度也就越高。 DDS 信号流程图如下图所示:

        这里相位累加器位数为 N 位( N 的取值范围实际应用中一般为 24~32),相当于把正弦信号在相位上的精度定义为 N 位,所以其分辨率为(\frac{1}{2})^{n}

若 DDS 的时钟频率为Fclk,频率控制字 fword 为 1,则输出频率为Fout =1*\frac{ Fclk}{2^{N}} ,这个频率相当于“基频”。若 fword 为 B,则输出频率为Fout =B*\frac{ Fclk}{2^{N}}

因此理论上由以上三个参数就可以得出任意的f_{0}输出频率。且可得出频率分辨率由时钟频率和累加器的位数决定的结论。当参考时钟频率越高,累加器位数越高,输出频率分辨率就越高。

从上式分析可得,当系统输入时钟频率Fclk不变时,输出信号频率由频率控制字 B 所决定,由上式可得: B =2^{N}*\frac{ Fout}{Fclk}。 其中 B 为频率字且只能取整数。为了合理控制 ROM 的容量,此处选取 ROM 查询的地址时,可以采用截断式,即只取 32 位累加器的高 M 位。这里相位寄存器输出的位数一般取 10~16 位。

频率控制字理解:

此变量A可以控制取点速度,实际就是对应框图中的频率控制字fword。time_r截取寄存器高11位与ROMd11位地址线对接,time_r低位做累加控制高位变化速率实现频率调控。

此为DDS核心所在!!

此部分正是框图中的相位累加器!!!!

相位控制字理解:

实际为控制相位初始值,说白了就是改变读取ROM数据表的起始位置!B不会改变读取频率,但可以改变初始位置,变量B就是相位控制字!!!!

二、公式讲解

                                        ​​​​​​​        ​​​​​​​        ​​​​​​​        Fout =A*\frac{ Fclk}{2^{N}}

若 DDS 的时钟频率为Fclk,N及对应time寄存器位宽,此处A为频率控制字,Fout为最终输出的信号频率。由此即可实现根据输出频率计算对应频率控制字的目的。

 计算举例:输出一个完整波形需要的时间:2048(11位RAM寄存器)*10ns(100MHz晶振) = 20480ns = 0.00002048s      对应频率为48828.125Hz

公式计算:A为22‘h10_0000(计算选取相位累加器高11位,[31:21],A取低11位[21:0],目的是为了每次增加可以改变寄存器第21位数值!)计算的频率为48828.125Hz

三、代码设计

1、验证部分顶层

`timescale 1ns / 1ps
module DDS_top(input                sys_clk,//100Mhzinput                sys_rst_n,// input      [31:0]    Fword,// input      [10:0]    Pword,output     [9 :0]    da_data);wire [10:0] rom_addr;
wire        clk_100mhz;    
assign    da_clk = clk_100mhz;parameter Fword = 32'd10000;
parameter Pword = 11'b0;DDS_FP u_DDS_FP(.sys_clk    (sys_clk)     ,
.reset_n    (sys_rst_n)     ,
.Fword      (Fword)       ,
.Pword      (Pword)       ,.rom_addr   (rom_addr)
);ROM_10x2048sin u_ROM_10x2048sin (.clka(sys_clk),    // input wire clka.addra(rom_addr),  // input wire [10 : 0] addra.douta(da_data)  // output wire [9 : 0] douta);endmodule

顶层给出固定的频率控制字,和相位控制字,下面进行理论计算:

Fout =10000*\frac{ 100000000}{2^{32}}=232.83Hz

2、验证部分DDS逻辑层

`timescale 1ns / 1psmodule DDS_FP(input                sys_clk,input                reset_n,input      [31:0]    Fword,input      [10:0]    Pword,output     [10:0]    rom_addr);
reg     [31:0]  r_Fword;
reg     [10:0]  r_Pword;reg     [31:0]  Fcnt;always @(posedge sys_clk ) beginr_Fword <= Fword;r_Pword <= Pword;
endalways @(posedge sys_clk or negedge reset_n) beginif(!reset_n)beginFcnt <= 32'd0;endelse beginFcnt <= Fcnt + r_Fword;end
endassign rom_addr = Fcnt[31:21] + r_Pword;endmodule

3、仿真部分代码

`timescale 1ns / 1ps
module DDS_tb;reg                sys_clk      ;reg                sys_rst_n    ;// reg      [31:0]    Fword     ;// reg      [10:0]    Pword     ;wire     [9 :0]    da_data      ;DDS_top u_DDS_top(
.sys_clk        (sys_clk),
.sys_rst_n      (sys_rst_n),
// .Fword       (),
// .Pword       (),
.da_data        (da_data)
);initial beginsys_clk = 1;
endalways #5 sys_clk = !sys_clk;initial beginsys_rst_n = 0;#200sys_rst_n = 1;
endendmodule

四、测试分析

1、仿真测试结果

 ​​​​​​​

2、上板验证 

测试频率与实际计算频率相差不大,验证成功,

五、未来改进

        可以使用外部按键控制,想要的频率,通过给出的计算公式计算对应的频率控制字,控制最终输出波形的频率,亦可多次例化ROM IP,添加其他不同波形。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/32611.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OneNote for Windows 10 下载

OneNote for Windows 10 安装 1.在浏览器中输入地址&#xff1a;https://apps.microsoft.com/detail/9wzdncrfhvjl?hlzh-cn&glUS2OneNote for Windows 10 - 在 Windows 上免费下载并安装 |Microsoft StoreOneNote 是用于在设备上捕获和组织你的一切内容的数字笔记本。快速…

为什么 C++ 允许不安全的代码(Bjarne Stroustrup)

为什么 C 允许不安全的代码? 也就是说&#xff0c;为什么 C 支持可以用来违反静态&#xff08;编译时&#xff09;类型安全规则的操作&#xff1f; 为了直接访问硬件&#xff08;例如&#xff0c;把整数当作指向设备寄存器的指针&#xff09;为了获取最佳的运行时效率和空间…

Content Provider:深入解析Android数据共享的核心组件

在Android开发中&#xff0c;Content Provider是一个重要的组件&#xff0c;它允许应用程序之间共享数据。它扮演着“数据访问中间层”的角色&#xff0c;为不同应用程序提供了一个统一的数据访问接口。以下将从技术难点、面试官关注点、回答吸引力以及代码举例四个方面&#x…

BUG cn.bing.com 重定向的次数过多,无法搜索内容

BUG cn.bing.com 重定向的次数过多&#xff0c;无法搜索内容 环境 windows 11 edge浏览器详情 使用Microsoft Edge 必应搜索显示"cn.bing.com"重定向次数过多&#xff0c;无法进行正常的检索功能 解决办法 检查是否开启某些科_学_上_网&#xff08;翻_墙&#xf…

jQuery中Validate方法总结

jQuery中Validate方法总结 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; jQuery Validate是一个流行的jQuery插件&#xff0c;用于在客户端对表单进行验证。它…

轻松重命名Windows用户Users目录下的文件夹名称

设置系统还原点 为避免设置失败&#xff0c;需提前准备好系统还原点以备份恢复系统。 打开系统属性&#xff1a; 在“系统保护”选项卡中&#xff0c;选择你想要保护的系统驱动器&#xff08;通常是C:驱动器&#xff09;。 点击“配置”按钮。 在弹出的窗口中&#xff0c;选…

【Python机器学习】NMF——将NMF应用于模拟信号数据

假设我们对一个信号感兴趣&#xff0c;它是由三个不同信号源合成的&#xff1a; import matplotlib.pyplot as plt import mglearnSmglearn.datasets.make_signals() plt.figure(figsize(6,1)) plt.plot(S,-) plt.xlabel(Time) plt.ylabel(Signal) plt.show()不幸的是&#xff…

大厂面试官问我:布隆过滤器有不能扩容和删除的缺陷,有没有可以替代的数据结构呢?【后端八股文二:布隆过滤器八股文合集】

往期内容&#xff1a; 面试官问我&#xff1a;Redis处理点赞&#xff0c;如果瞬时涌入大量用户点赞&#xff08;千万级&#xff09;&#xff0c;应当如何进行处理&#xff1f;【后端八股文&#xff08;1&#xff09;】-CSDN博客 本文为【布隆过滤器八股文合集】初版&#xff0c…

数据结构:冒泡排序,选择排序,插入排序,希尔排序的实现分析

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 小新的主页&#xff1a;编程版小新-CSDN博客 1.冒泡排序 1.1算法思想 冒泡排序的基本思想就是&a…

由浅入深,走进深度学习(4)

各位小伙伴大家好&#xff0c;这期内容是深度学习基础的一个进阶&#xff0c;也可以说是夯实一下很多细节内容 个人感受&#xff1a;动手敲一遍&#xff0c;带着思考&#xff0c;会有不一样的感受&#xff01;&#xff01;&#xff01; 代码是比较多的&#xff0c;有很多内容…

全局变量和局部变量

全局变量未初始化&#xff0c;则它的值为0&#xff1b; 局部变量未初始化&#xff0c;则它的值为随机值&#xff1b; 局部变量的作用域是变量所在的局部范围; 全局变量的作用域是整个工程; 生命周期&#xff1a; 变量的生命周期指的是变量从创建到销毁的整个阶段。 局部变量的生…

react实现路由拦截器

1. 路由拦截的概念 路由拦截&#xff1a;在用户导航到某个路由之前&#xff0c;通过某种逻辑来拦截、检查或修改导航行为。它可以用于实现权限控制、身份验证、页面加载前的准备工作等场景。 2. React Router中的路由拦截实现 2.1 使用<Route>组件的render属性 在Rea…

每天一个项目管理概念之关键路径

在项目管理中&#xff0c;关键路径分析&#xff08;Critical Path Method, CPM&#xff09;是计划和控制项目时间表的重要工具。关键路径是项目网络图中从开始到结束的最长路径&#xff0c;它确定了完成整个项目所需的最短时间。任何关键路径上的任务延误都将直接导致整个项目延…

mysql插入blob或longblob的字符串

mysql字段格式是blob的时候&#xff0c;直接插入字符串会异常 insert table (str),values (aaaa)会异常 需要将字符串转为0x格式的16进制字符串才行 aaaa转换之后为61616161 insert table (str),values (0x61616161)java将字符串转16进制字符串 "0x"DatatypeConver…

使用zdppy结合onlyoffice开发第一个网页文档应用

docserver环境搭建 禁用JWT 加载镜像&#xff1a; docker load -i docserver:7运行容器&#xff1a; docker run -itd -p 8080:80 --name docserver -e JWT_ENABLEDfalse --restartalways onlyoffice/documentserver:7.3.2docker run -itd -p 8080:80 --name docserver -…

字节跳动:从梦想之芽到参天大树

字节跳动掌舵人&#xff1a;张一鸣 2012年&#xff1a;梦想的起点&#xff1a;在一个阳光明媚的早晨&#xff0c;北京的一座普通公寓里&#xff0c;一位名叫张一鸣的年轻人坐在电脑前&#xff0c;眼中闪烁着坚定的光芒。他的心中有一个梦想——通过技术改变世界&#xff0c;让…

如何使用Java实现高效的多线程编程

如何使用Java实现高效的多线程编程 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 引言 在当今软件开发领域中&#xff0c;多线程编程是一项关键技能。它能够…

嵌入式实验---实验六 I2C传输实验

一、实验目的 1、掌握STM32F103I2C传输程序设计流程&#xff1b; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、本案例利用I/O端口通过KEY01按键来控制STM32F103R6向24C02写入“hello”&#xff0c;通过另外一个按键KEY02来控制STM32F103R6从24C02读取“hello”&#x…

又一个前后端分离的整合了OpenAI大模型的高并发、高性能和可扩展的项目完结了,写到简历上,嘎嘎强!

大家好&#xff0c;我是冰河~~ 经过四个多月的坚持&#xff0c;《分布式IM即时通讯系统》终于完结了&#xff0c;也感谢大家这四个多月以来的坚持和陪伴&#xff0c;也相信大家在《分布式IM即时通讯系统》专栏中&#xff0c;学到了不少知识和技术。接下来&#xff0c;我们就一…

[C++][设计模式]介绍

目录 1.设计模式1.何为设计模式&#xff1f;2.深入理解面向对象3.软件设计的目标4.三大模式及其特点5.设计模式分类 2.面向对象设计原则1.为什么要面向对象2.重新认识面向对象3.面向对象设计原则4.C对象模型 3.重构1. 重构获得模式(Refactoring to Patterns)2.重构关键技法 4.代…