基于FPGA的DDS设计(一)
最近在学习基于FPGA的DDS设计,借此机会把学习过程记录下来,当作自己的学习笔记也希望能够帮助到学习DDS的小伙伴。
DDS(Direct Digital Synthesizer)直接数字合成器,这是直译过来的名字。设计人员一般把它叫做信号发生器,用它来产生一些数字意义上的波形。它的意义还是挺大的,例如我们学习滤波器,就需要一个高低频率叠加的波形,现时生活中到处都是,可以在设计中,怎么能做出这样的波形呢?学习各种载波调制,需要将信息加载到载波上,而载波也一般都是一定频率的正弦波。DDS就是能够产生这种波形,对于学习数字信号处理以及信号调制解调等有很大的作用。
FPGA是数字电路,怎么产生模拟的波形呢?如果单纯的使用FPGA是无论如何也产生不了连续不断的波形,一般都是使用FPGA产生数字信号,再利用DAC(Digital-to-Analog Converter)转化成为模拟的波形(如图1)。DAC芯片是一堆模拟电路的东西了,如果感兴趣的小伙伴可以在自己学习一下数字信号转化为模拟信号的过程。

图1
FPGA是数字信号,通过DAC转化为模拟值,笔者在进行学习的时候一直有个疑问:既然FPGA是数字信号,那么也就只能输出数字信号,输出相邻的两个点中间一定是有一定距离的,输出的模拟波形应该像楼梯一样(有一定的幅值跳跃),而不是连续变化的,像这种情况下还是我们还可以用吗?答案是肯定的,如果“楼梯”的高度跳跃很小,并且在一个周期中有很多小的跳跃,那么就是可以用的。其实微积分的概念和这个道理应该差不多就是用无限多的矩形来近似曲线(如图2)。

图2
所以在设计时,只要将波形的一个周期(周期波形)中分成N段输出就可以了。
DDS的实现一般都是由频率控制器、相位累加器和波形存储器构成(如图3)。

图3
刚刚开始的时候接触到这个信息,笔者也不太理解,经过一段的时间思考,大概明白了其中的设计原理。我们直接从最终的输出开始分析,要输出的一个波形(数字意义上),例如正弦波。那么怎么输出呢,可以给出一个公式sin(2*pi*n/256),将n从0增长到255,就可以输出一个波形。如果这么写的话,就已经把一个周期分成了256份,也可以分成任意份,为了方便数字电路设计,一般都是2的整数次幂份。以下分析都当作一个周期分为256份。n等于一个数值就会输出一个值,把n所对应的位置看作是相位。例如n等于64时,输出的值正好对应于相位pi/2时。在FPGA中去计算sin,一般都是利用查表法,也就是说将一个周期分为N份,当输入的值比较接近与某一个相位时,就把这个相位点的值输出。那其实也就是把波形等分多份,存储在存储器中,而此时存储器就叫做波形存储器。存储器的输出是按照输入地址来决定的,如果想要输出一个完整的不断的波形,就需要地址从最小到最大不变循环,而存储器就会不断的输出波形。地址从最小到最大的累加,就被成为相位累加器。如果相位累加器1S从最小到最大循环了1000次,那么输出的波形的频率就为1KHz。故而相位累加器累加的速度决定输出波形的频率,而累加速度是由外部控制器来决定,所以此控制器被称作频率控制器。
原理就是上述的那样,下面可以考虑如何来实现上述的过程。
在设计中,笔者采用INTEL FPGA来实现,故此采用Quartus Prime 18。首先制作波形存储器,在FPGA中有很多存储器资源可以来用,在此选择ROM来当作存储器。利用ROM当存储需要制作初始化文件.mif或者.hex,这两种都可以,在这里采用.mif文件。
.mif在Quartus 中显示为一个一个小区域(如图4),但是其实就是一种文件格式(如图5)。

图4

图5
利用某些计算工具将数值计算出来,然后填入表格中,这种速度太慢,也太麻烦。我们一般采用下面所述的两种方法:
利用mifmaker软件生成(QQ群:173560979群文件中),此软件用起来比较简单。只需要简单的设置“设定波形”即可。在设定成功后,点击“文件->保存”即可生成对应的.mif文件(如图6)。

图6
另外一种方法就是利用matlab实现,此方法要求设计者要有一定的matlab基础。源码如下:
clear;
clc; width = ;
depth = ; file_handle = fopen('sin.mif','w+');
fprintf(file_handle,'--Created by Author xxx\r\n');
fprintf(file_handle,'WIDTH = %d;\r\n',width);
fprintf(file_handle,'DEPTH = %d;\r\n',depth);
fprintf(file_handle,'ADDRESS_RADIX = HEX;\r\n');
fprintf(file_handle,'DATA_RADIX = HEX;\r\n');
fprintf(file_handle,'CONTENT BEGIN\r\n');
for i = : depth-
fprintf(file_handle,'%4x : %4x ; \r\n',i,floor((0.5+0.5*sin(*pi*i/depth) ) *(^width - 1)));
end
fprintf(file_handle,'END;\r\n');
fclose(file_handle);
产生了.mif后,就可以加载到ROM中。在quartus工程中,采用50MHz的时钟来进行驱动整个设计,让rom的地址每个时钟周期增加1。经过仿真可以得到正弦波(如图7)。

图7
产生了正弦波,在设置modelsim时,因为波形是按照无符号生成的数据,所以在设置成为模拟之前要先把进制改为无符号类型。即可产生图7波形。经过使用modelsim工具测试,产生的波形的频率为195.313KHz。我们自己也算以下:系统的驱动时钟为50MHz,一个周期为20ns,256个周期输出一个完整的波形。所以波形的周期为256x20ns=5120ns,经过计算频率为195.3125KHz,与上述使用modelsim工具测试结果一直,只是modelsim测试保留了频率的两位小数而已。
相位累加器每次累加1,产生的波形的频率为195.313KHz,那么只要改变每次累加的数字就可以得到其他频率。如果每次增加的是整数比较好办,那如果每次增加的是带有小数呢?又该如何实现呢?
笔者水平有限,如有不妥之处,恳请大佬指出。
欢迎加好友探讨QQ:746833924,QQ群:173560979。
基于FPGA的DDS设计(一)的更多相关文章
- 基于FPGA的DDS设计(二)
在DDS设计中,如果相位累加器每个时钟周期累加1,就会输出频率为195.313KHz的波形.如果每个时钟周期累加2,就会输出频率为2*195.313KHz的波形·······,如果每两个时钟周期累加1 ...
- 基于FPGA的DDS任意波形发生器设计
一.简介 DDS技术最初是作为频率合成技术提出的,由于其易于控制,相位连续,输出频率稳定度高,分辨率高, 频率转换速度快等优点,现在被广泛应用于任意波形发生器(AWG).基于DDS技术的任 ...
- 基于FPGA(DDS)的正弦波发生器
记录背景:昨晚快下班时,与同事rk聊起怎么用FPGA实现正弦波的输出.我第一反应是利用高频的PWM波去滤波,但感觉这样的波形精度肯定很差:后来想起之前由看过怎么用FPGA产生正弦波的技术,但怎么都想不 ...
- 38.基于FPGA的FIR设计二
利用fdatool工具生成的滤波器系数与用代码生成的系数不一致,在网上查询得知,fdatool生成的滤波器系数是有符号小数,而且是浮点型,而代码生成的滤波器系数是定点型有符号数,故不一样. 浮点型数据 ...
- 优化基于FPGA的深度卷积神经网络的加速器设计
英文论文链接:http://cadlab.cs.ucla.edu/~cong/slides/fpga2015_chen.pdf 翻译:卜居 转载请注明出处:http://blog.csdn.net/k ...
- 自己动手写CPU(基于FPGA与Verilog)
大三上学期开展了数字系统设计的课程,下学期便要求自己写一个单周期CPU和一个多周期CPU,既然要学,就记录一下学习的过程. CPU--中央处理器,顾名思义,是计算机中最重要的一部分,功能就是周而复始地 ...
- 基于FPGA的XPT2046触摸控制器设计
基于FPGA的XPT2046触摸控制器设计 小梅哥编写,未经许可,文章内容和所涉及代码不得用于其他商业销售的板卡 本实例所涉及代码均可通过向 xiaomeige_fpga@foxmail.com 发 ...
- 基于FPGA的HDMI显示设计(三)
上一篇:基于FPGA的VGA显示设计(二) 10月10日 ~ 20日期间实习,令我万万没想到的是实习题目是 “便携式高清电视显示屏测试系统原型设计” 也就是 “基于FPGA的视频显示”. 实习要求用 ...
- 基于FPGA的VGA显示设计(二)
上一篇:基于FPGA的VGA显示设计(一) 参照 CrazyBingo 的 基于FPGA的VGA可移植模块终极设计代码 的工程代码风格,模块化处理了上一篇的代码,并增加了一点其它图形. 顶层 ...
随机推荐
- linux(centos7)下SVN服务器搭建手札
linux(centos)下SVN服务器如何搭建?说到SVN服务器,想必大家都知道,可以是在LINUX下如何搭建SVN服务器呢?那么今天给大家分享一下linux(centos)搭建SVN服务器的思路! ...
- log4j配置详解(非常详细)
Log4J的配置文件(Configuration File)就是用来设置记录器的级别.存放器和布局的,它可接key=value格式的设置或xml格式的设置信息.通过配置,可以创建出Log4J的运行环境 ...
- ActionContext和ServletActionContext小结(转)
ActionContext和ServletActionContext小结 1. ActionContext 在Struts2开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Act ...
- phantomJs页面操作
因为phantomjs能加载和操纵页面,它可以自动化地完美执行页面的各种操作. 操作文档: 脚本的被执行,就像它真的正在web 浏览器上运行一样. 下面的脚本,是读取元素id为myagent的文本内容 ...
- Spring MVC 常用Jar包
spring:http://maven.springframework.org/release/org/springframework/spring/ jackson:http://repo1.mav ...
- 用华为eNSP模拟器配置Hybrid、Trunk和Access三种链路类型端口
上一篇文章写到三层交换机实现多个VLAN之间互相通讯,有朋友提问要如何进行配置,可有案例分析.其实那天我在写的时候也有做过模拟,只是后来没有保存.今天重新模拟一次,并附上详细配置命令,希望能够帮助到大 ...
- 远程桌面报错解决:No Remote Desktop License Servers Available
摘 要 用户发来反馈,使用部门Windows跳板机报错:The remote session was disconnected because there are no Remote Desktop ...
- 转: C# 的结构剖析
原文链接:http://www.cnblogs.com/jiajiayuan/archive/2011/09/20/2181582.html 本文意在巩固基础知识,并不是对其进行深入剖析,还望理解.本 ...
- Celery学习--- Celery操作之定时任务
celery支持定时任务,设定好任务的执行时间,celery就会定时自动帮你执行, 这个定时任务模块叫celery beat 文件定时执行任务 项目前提: 安装并启动Redis celery_Sche ...
- Centos7下Mysql通过.frm和.ibd恢复数据
通过.frm和.ibd文件恢复表结构和数据 这里以hue数据库中的desktop_document2表为例 分成两步骤,先去表结构,再取数据,最好在一个用完就可以删除的数据库中进行 取表结构篇: 1. ...