FPGA控制DDS产生1CLK周期误差的分析(二)
前文简短的介绍了DDS的产生原理,其实相当的简单,所以也不需要多做解释,本文详细阐述一下在调试DDS的过程中所产生的一个bug
问题发现
正如上文所述,再用FPGA控制存储在rom中的波形信号输出之后,在上板之前,我们可以先用仿真软件仿真一下,看看波形是否有误。我们的测试条件要求为:从2550Hz开始,每间隔1s的周期以20Hz的步长向下递减至2310Hz的频率,仿真波形如下所示(为节省仿真时间,我们将扫频间隔缩短):
不知大家是否能看清上图中的周期结果分析,按照上图所示,2550Hz、2530Hz除开频率交接处会有一定的抖动之外,在扫频周期中的频率是比较稳定的,但是当我们看到2510Hz的扫频周期过程中却发现,波形的周期呈现为398420ns、398400ns的周期变化,虽然说二者的周期对应基本上都为2510Hz,但是对频率信号敏感的场合是不能接受的。本文便对这一问题进行考究。
问题探究
首先,我们追根溯源,DDS信号发生的来源就是ROM当中存储的波形数据,而波形数据的来源是所输入的地址addr,这么一来我们就将目光放在addr上面。
addr是一个12位的变量,来源于频率信号叠加寄存器的高12位,为什么要设置叠加器为32位,就像前文所述,为了提高但个周期的分辨率,使得输出更加精确。接下来让我们分别来看看398420 ns和398400 ns的波形细节。
我们发现多的20ns(一个CLK周期)来源于高电平期间的差异,所以我们进一步的查看高电平的细节。先来看看199220ns的这个高电平。
可见,高电平的持续时间应该为 20ns × 5 × (2048-0) = 204800ns,这和我们的波形图上实现显示的差了204800ns - 199220ns = 5,580ns。我们记为error1。
然后再来看199200ns的这个高电平。
上面两幅图的高电平的持续时间应该为 20ns × 5 × (2048-0) = 204800ns,这和我们的波形图上实现显示的差了204800ns - 199200ns = 5600ns。我们记为error2。
好了,通过分析波形我们发现逻辑设计上是没有问题的,该在什么时候下降,什么时候上升都符合要求,那么其中的error1、2是从何而来的呢?这时候我们注意到上面的这个5,代表5个时钟周期变化一次地址,那么此时我们不禁要问,这个5个时钟周期变化一次,它真的那么诚实可靠,人畜无害吗,答案是否定的。
像上面两幅这样的问题时序还有很多,相信数量也是5600ns / 20ns = 280个。好了接下来问题就是分析问什么会少一个了。
讲了这么久,终于该回到代码层面了。让我们看一下地址递增的部分代码。
reg [31:0] freq_cnt;
assign addr = freq_cnt[31:20] + phase_offset;
always @(posedge sys_clk or posedge sys_rst)beginif(sys_rst)freq_cnt <= 32'd0;elsefreq_cnt <= freq_cnt + freq_k;
end
从上图中可以看到。此时的freq_k为215607,而我们的地址是从220开始进位的,也就是说计数220 = 1,048,576次之后,addr + 1。那么215607需要加多少次呢?如下表所示:(表中标红表示进位)
上表我想已经表示的很明白了,因为每一轮都会有一个误差叠加,最后不断累积起来就会造成每一个周期输出的周期数不一样,虽然每一次都只是一个CLK的误差,但是总归是有误差的。目前我们给的频率参数是2510Hz,有这个现象,那前面2550、2530Hz有没有这个情况呢?答案是有的,如下图所示:
同样的,2048 × 20 × 5 = 204800ns,但是实际上仿真结果为:196080ns,也是有这个误差的。至于为什么此时没有出现前面那样子一个CLK周期的误差,原因我想就是刚刚好误差的次数为偶数,根据差分原理消除了。不论怎样,这个问题我们都应该消除,下面探讨一下解决办法。
问题解决
知道了问题所在,接下来找找解决办法,既然已经确定这个是算法的问题,就从算法设计上下功夫。首先可以确定的一点是,我们既然已经得到对应的freq_k即每一次叠加的值,那么每一次就应该叠加这么多,也就是说每一次就应该加这么多才能得到正确的输出频率,如果修改了这个输出的频率值也就是错的了。
解决办法1:一开始我想的办法是,依旧按照这个计数值叠加,如果叠加的值超过了220 = 1,048,576马上让叠加的值清0,然后让addr+1。这样子相当于舍弃了每一次的叠加误差。但是后来想了想,这样子的频率输出误差也太大了,分析如下:假设我刚好要计数5次,那么每一次计数的值就是1048576 / 5 = 209,715.2 ≈209716(必须要向上取整);而如若要计数计数6次,对应的就是174,763;4次对应262,144。这样子按照之前根据频率计算次数的公式对应回去的频率分别为:3,051.8Hz、2,441Hz和2,034.5Hz,也就是说,位于这三个点之间的设定频率都会被忽略,然后变成上述的固定点的频率值,有点类似于模数转换中的量化误差。而如若要减少量化误差,办法是降低addr跳变的临界值也就是1048576,即在N不变的前提下,提高ROM的深度,但这总归不是个好办法。
解决办法2:通过上述分析我们知道,叠加误差不能够省略,那么我们又如何让叠加误差“进场”呢?通过思考,我发现叠加误差本来就要进去的,那么转变枪头,将目光从叠加误差转移到波形误差,为什么上一个周期的叠加误差和下一个周期的叠加误差会不同?如何才能让它们变得相同?为什么会不同,因为每一个周期在结束的时候,对应的freq_cnt的不为0,这边就也会有一个误差(freq_cnt就是那个32位的寄存器,取高12位作为ROM的寻址信息)。还是上面那个例子,地址+1所需要的叠加量为1 048 576,然后我们每一次始终到来时给它 +215 607,但是如果每一个周期结束时都会有一个会累加的误差,当这个误差累加到215 607时,就省了一个时钟周期的叠加,此时误差重新回0,这就是为什么会出现周期之间会有一个CLK周期的误差的原因,之所以前面2550Hz和2530Hz没有出现,是因为他们每一次叠加的误差量太小,而仿真的时间太短,还没来得及叠加上去就跳到下一个频率周期了!针对这个周期间的误差,我想到解决办法是,检测到一个周期输出完毕之后,手动的将叠加器变量给清空,也就是说人为消除周期叠加误差。这个误差和上面那个不同,上面那个累加误差决定着输出的精度,这个周期误差的值不会超过一个地址周期,可以忽略不计,虽然精度会受损,但总归是消除了这个误差了。
结语
起始本次设计的bug来源就是算法的问题,最后的解决办法也想但简单就是清个0就好了。啰嗦了这么多总归是讲完了,说实话,当初在调DDS的时候,根本就没想这么多,只觉得输出的时候频率正确即可。也根本发现不了这个问题,毕竟1个CLK周期的误差,真的太难发现了。所幸一位朋友发现了这个问题,在与他交流许久后才做了这次的实验,最终也是不负使命,找出了问题所在,也于此感谢他的细心观察的结果。
资源链接
百度网盘链接:链接:https://pan.baidu.com/s/1LqOMz0f9FBW-6bxZFUzlQA?pwd=wvq6
提取码:wvq6
CSDN链接:FPGA控制AD9767实现DDS信号发生器
相关文章:

FPGA控制DDS产生1CLK周期误差的分析(二)
前文简短的介绍了DDS的产生原理,其实相当的简单,所以也不需要多做解释,本文详细阐述一下在调试DDS的过程中所产生的一个bug 问题发现 正如上文所述,再用FPGA控制存储在rom中的波形信号输出之后,在上板之前࿰…...

这一次,吃了Redis的亏,也败给了GPT
关注【离心计划】,一起离开地球表面 背景 组内有一个系统中有一个延迟任务的需求,关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案,关于时间轮,这边小苏有一个大学时候做的demo: https://github.com/JA…...

第一章 信息化知识
1、信息是客观事物状态和运动特征的一种普遍形式,信息的概念存在两个基本的层次,即本体论层次和认识论层次: 本体论层次:就是事物的运动状态和状态变化方式的自我表述认识论层次:就是主体对于该事物的运动状态以及状态…...

如何用matlab工具箱训练一个SOM神经网络
本站原创文章,转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com本文展示如何用matlab工具箱训练一个SOM神经网络的DEMO并讲解其中的代码含义和相关使用说明- 01.SOM神经网络DEMO代码 -- 本文说明 -下面,我们先随机初始化一些样本点,然后…...

音视频技术开发周刊 | 285
每周一期,纵览音视频技术领域的干货。新闻投稿:contributelivevideostack.com。GPT-4 Office全家桶发布谷歌前脚刚宣布AI工具整合进Workspace,微软后脚就急匆匆召开了发布会,人狠话不多地祭出了办公软件王炸——Microsoft 365 Cop…...

安装flume
flume最主要的作用就是实时读取服务器本地磁盘的数据,将数据写入到hdfs中架构:开始安装一,上传压缩包,解压并更名解压:[rootsiwen install]# tar -zxf apache-flume-1.9.0-bin.tar.gz -C ../soft/[rootsiwen install]#…...

为工作排好优先级
工作,是干不完的,因此我们需要分清轻重缓急,为它们划分优先级,这样才不至于让自己手忙脚乱。 给手头的事情排上正确的优先级,是一项很重要的工作能力。 优先级有很多考量,并不是简单的先来后到的线性时间…...

超专业解析!10分钟带你搞懂Linux中直接I/O原理
我们先看一张图: 这张图大体上描述了 Linux 系统上,应用程序对磁盘上的文件进行读写时,从上到下经历了哪些事情。 这篇文章就以这张图为基础,介绍 Linux 在 I/O 上做了哪些事情。 文件系统 什么是文件系统 文件系统࿰…...

【C++】面试101,用两个栈实现队列,包含min函数的栈,有效括号序列,滑动窗口的最大值,最小的K个数,倒置字符串,排序子序列,跳跃,数字三角形,蓝肽子序列
目录 1. 用两个栈实现队列 2.包含min函数的栈 3.有效括号序列 4.滑动窗口的最大值 5.最小的K个数 6.倒置字符串 7.排序子序列 8.数字三角形(蓝桥杯,学习一个大佬的博客....) 9.跳跃(蓝桥杯) 10.蓝肽子序列 1. 用…...

WPF 认识WPF
什么是WPF?WPF是Windows Presentation Foundation(Windows展示基础)简称,顾名思义是专门编写表示层的技术。WPF绚丽界面如下:GUI发展及WPF历史?Windows系统平台上从事图形用户界面GUI(Graphic User Interface)已经经历了多次换代,…...

【建议收藏】PHP单例模式详解以及实际运用
PHP单例模式详解以及实际运用 什么是单例模式? 首先我们百度百科他怎么说? 单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如&a…...

【十二天学java】day04-流程控制语句
第一章 流程控制语句 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能。 1.1 流程控制语句分类 顺序结构 判断…...

Pandas 与 PySpark 强强联手,功能与速度齐飞
Pandas做数据处理可以说是yyds!而它的缺点也是非常明显,Pandas 只能单机处理,它不能随数据量线性伸缩。例如,如果 pandas 试图读取的数据集大于一台机器的可用内存,则会因内存不足而失败。 另外 pandas 在处理大型数据…...

【Zabbix实战之部署篇】docker部署Zabbix+grafana监控平台
【Zabbix实战之部署篇】docker部署Zabbix+grafana监控平台 一、Zabbix介绍1.Zabbix简介2.Zabbix的优点3.Zabbix各组件介绍4.Zabbix架构图二、grafana介绍1.grafana简介2.grafana特点三、实践环境规划四、检查本地docker环境1.检查操作系统版本2.检查docker版本3.检查docker服务…...

acm省赛:高桥和低桥(三种做法:区间计数、树状数组、线段树)
题目描述 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上ÿ…...

stm32-定时器详解
0. 概述 本文针对STM32F1系列,主要讲解了其中的8个定时器的原理和功能 1. 定时器分类 STM32F1 系列中,除了互联型的产品,共有 8 个定时器,分为基本定时器,通用定时器和高级定时器基本定时器 TIM6 和 TIM7 是一个 16 位…...

《硬件架构的艺术》读书笔记:Chapter 1 亚稳态的世界
Chapter 1 亚稳态的世界 一、简介 同步系统中,数据和时钟有固定的因果关系(在同一时钟域(Clock Domains))中,只要数据和时钟满足建立时间和保持时间的要求,不会产生亚稳态(meastable) 静态时序分析(STA) 就是基于同步电路设计模型而出现的&am…...

开箱即用的密码框组件
写了一个小玩具,分享一下 - 组件功能: 初次进入页面时,密码隐藏显示,且无法查看真实密码 当修改密码时,触发键盘,输入框则会直接清空 此时输入密码,可以设置密码的隐藏或显示: …...

ChatGPT能否取代程序员?
目录ChatGPT能否取代程序员?ChatGPT和程序员的工作内容和工作方式ChatGPT和程序员的共同点程序员的优势程序员的实力ChatGPT和程序员的关系结论惊喜ChatGPT能否取代程序员? ChatGPT是一种非常普遍的人工智能(AI)系统,…...

案例分享 | 金融微服务场景下如何提升运维可观测性
云原生环境下金融业务的微服务化改造以及分布式架构的部署,使得业务与开发部门的关联更为紧密,传统运维监控已满足不了业务运营需求,亟需建设具备可观测性的运维体系。所以这次我们以某金融客户的实践案例为例,跟大家说一说在金…...

CentOS8提高篇3:Centos8安装播放器(mplayer vlc)
1. 准备工作(需要配置epel, rpmfusion源); 配置epel源 下载epel dnf install epel-release 配置rpmfusion源 下载rpmforge dnf install rpmfusion-free-release-8.noarch.rpm 2. 安装mplayer和vlc 直接dnf安装 # dnf install mplayer # dnf install v…...

MySQL-存储过程
什么是存储过程我们前面所学习的MySQL语句都是针对一个表或几个表的单条 SQL 语句,但是在数据库的实际操作中,并非所有操作都那么简单,经常会有一个完整的操作需要多条SQL语句处理多个表才能完成。例如,为了确认学生能否毕业&…...

经典七大比较排序算法 · 下 + 附计数和基数排序
经典七大比较排序算法 下 附计数和基数排序1 插入排序1.1 算法思想1.2 代码实现1.3 插入排序特性2 希尔排序2.1 算法思想2.2 代码实现2.3 希尔排序特性3 七大比较排序特性总结4 计数排序4.1 算法思想4.2 代码实现4.3 计数排序特性5 基数排序5.1 算法思想5.2 代码实现1 插入排…...

HTTPS协议,看这篇就够了
不安全的HTTP 近些年来,越来越多的网站使用 HTTPS 协议进行数据传输,原因在于 HTTPS 相较于 HTTP 能够提供更加安全的服务。 很多浏览器对于使用 HTTP 协议的网站会加上『警告』的标志表示数据传输不安全,而对于使用 HTTPS 协议的网站会加上…...

C语言学习之路--结构体篇
目录一、前言二、结构体的声明1、结构的基础知识2、结构的声明3、结构体成员的类型4、结构体变量的定义和初始化三、结构体成员的访问四、结构体传参一、前言 本人是一名小白,这一篇是记录我C语言学习中的结构体的所学所得,仅为简单的认识下C语言中的各…...

【LINUX】初识文件系统
文章目录一、前言二、回顾C语言文件操作三、初识系统调用openreadwriteclose四、文件系统初识五、结语一、前言 二、回顾C语言文件操作 int main() {FILE* fp fopen("log.txt", "w");if (fp NULL){perror("fopen");}int cnt 0;fputs("…...

金三银四Java面试题及答案整理(2023最新版) 持续更新
作为一名优秀的程序员,技术面试是不可避免的一个环节,一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 如果你参加过一些大厂面试,肯定会遇到一些这样的问题: 1、看你项目都用的框架,熟悉 …...

7个角度,用 ChatGPT 玩转机器学习
大家好,我是机器学习科普创作者章北海mlpy,探索更高效的学习方法是我一直等追求。现在的初学者太幸福了,可以利用ChatGPT来帮助你学习机器学习的各个方面。 比如【个人首测】百度文心一言 VS GPT-4这篇文章中,我就用文心一言、GP…...

关于多层板,你了解多少?
01 前言 大家好,我是张巧龙。好久没写原创了,记得之前刚接触PCB时,还在用腐蚀单层板,类似这种。 慢慢随着电子产品功能越来越多,产品越来越薄,对PCB设计要求越来越高了,复杂程度也随之增加。因此…...

使用sqlalchemy-gbasedbt连接GBase 8s数据库
测试环境: 操作系统:CentOS 7.9 64-bit数据库版本:GBase8sV8.8_AEE_3.0.0_1,对应的CSDK版本为3.0.0_1 1,确认安装python3 确认已经安装python3和python3-devel [rootlocalhost test]# python3 -V Python 3.6.8如果…...