赞
踩
(原创声明:该文是作者的原创,面向对象是FPGA入门者,后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门,作者不光让大家知其然,还要让大家知其所以然!每个工程作者都搭建了全自动化的仿真环境,只需要双击top_tb.bat文件就可以完成整个的仿真(前提是安装了modelsim),降低了初学者的门槛。如需整个工程请留言(WX:Blue23Light),不收任何费用,但是仅供参考,不建议大家获得资料后从事一些商业活动!)
上一节课实现了将一个正弦波的数据信号存储到ROM中,然后采用系统时钟从ROM中读出来就是一个固定周期的正弦波。比如系统时钟是100MHz,一个正弦波是2^8=256个点,那此时正弦波的周期就是100_000_000/256,也就是390.625KHz。如果想得到其它频率的正弦波要怎么做呢?你可以会说改变系统时钟呀,也可以,这是一个方法,但是非常不实用,因为系统时钟一般是固定的,如果我需要一个变频正弦波的功能,总不能时刻跳转系统时钟把?那应该怎么办呢,可以使用DDS来实现。
DDS 是直接数字式频率合成器(Direct Digital Synthesizer)的英文缩写,是一项关键的数字化技术。与传统的频率合成器相比,DDS 具有低成本、低功耗、高分辨率和快速转换时间等优点,广泛使用在电信与电子仪器领域,是实现设备全数字化的一个关键技术。作为设计人员,我们习惯称它为信号发生器,一般用它产生正弦波、锯齿波、方波等不同波形或不同频率的信号波形,在电子设计和测试中得到广泛应用。
上面的一段话是在网上找的,DDS到底是什么呢?其实就是我有了一个周期正弦波的数据(假如256个),在系统时钟下(假如100MHz)读出该正弦波的周期是390.625KHz,那通过DDS就可以得到390.625KHz整数倍的频率的正弦信号,比如781.25KHz、1171.875KHz、1156.25KHz等等,但是这个频率也不能无限增加下去,都一定的程度波形就会失真了。还有就是不光可以正弦波,也可以得到余弦波,只需要更改初始的相位即可!
笔者面试过很多刚毕业的大学生,有志从事FPGA的开发,问到有没有FPGA的开发经验,很多都说毕业设计是实现DDS,但是让讲一下原理,很多人又讲不清楚,DDS的实现其实非常简单,作为一个毕业设计还是有点单薄,下面就说一下DDS的原理。
假设一个周期波形的点数是K,系统时钟是Fs,那用系统时钟读取波形数据,此时波形的周期是Fs/K;假如我们想得到一个新的比Fs/K大的波形周期Fn,那Fn/(Fs/K)取整数会得到一个值,这个值就是频率控制字F_WORD,只要我们得到了F_WORD,对读ROM的地址信号进行处理,既可以得到期望频率的波形。
还是上面的例子,用系统时钟直接读256个点就会产生390.625KHz的正弦波,如果想得到781.25KHz的正弦波,那频率控制字F_WORD就取2,就是读ROM地址的时候每次加2,也就是隔一个点读一个点,这样其实读了128个点,100_000_000/128=781.250KHz!从这个地方也能看出来DDS的频率不能无穷大,因为频率越大,点数越少,波形失真越严重!如果想得到更高的频率,可以增加一个周期波形的点数,比如512,1024,2048,4096......
下面是一个DDS的标准框图。频率控制字控制波形的频率,相位控制字控制波形的相位。
其实这个还有一个问题,假如我们想得到1MHz的波形,根据上面的计算F_WORD=1M/(100M/256)=2.56,但是ROM的地址只能增加整数,可以是2,也可以是3,如果F_WORD=2,正弦波输出频率是781.250KHz,如果F_WORD=3,正弦波输出频率是1.171875MHz,差距都有点大!应该如何处理?可以扩展累计器的位数,比如将累计的位数由8位扩展到32位!同时将频率控制字F_WORD和相位控制字也扩展到32位!
意思就是假设ROM中一个正弦波的周期是2的32次方个点,即ROM中存储了4294967296个数据!这时候如果要产生1MHz的正弦波,那频率控制字F_WORD=1M/(100M/2^32)=42949672,即累加器每次增加42949672即可!
最后的问题,累计器是32位的,但是ROM最终还是8位的?要怎么对应取ROM里面的数据呢?其实非常简单,取累计器的高8位作为读取ROM中数据的地址即可!
原因就是32位的数据把8位的数据放大了,本例就是把2.56放大了2的24次方倍,把小数放大成了整数,这样每次累计就不会丢失小数的细节了;最后从ROM里面读数的时候,又舍弃的低位的细节,只取高位就可以反应数据的实际变化。就比如我们拍一张4K的照片,如果直接拍细胞几乎拍不到任何细节,但是如果我们用显微镜放大后再拍4K的照片,图像大小一样的,但是细节丰富了很多!!!
下面是FPGA的设计,可以看看dds有多简单!要求是系统时钟是100MHz,低电平复位,初始输出1MHz的余弦波,然后频率控制字增加,观察一下输出波形的变化。
确认一下频率控制字F_WORD=1M/(100M/2^32)=42949672,由于是余弦波输出,那相位控制字P_WORD就从ROM的中间位置开始读数,即2^32/2=2^31=2147483648;F_WORD_ADD就是过一段时间将频率控制字增加的数值,可以观察一下输出频率的变化。
下面主要是实现系统时钟每计数200次,频率控制字的值加F_WORD_ADD,用来模拟输出波形频率的增大。
如果只需要输出固定频率的波形,dds实际上只需要下面一个always模块即可,这也是我为什么说dds的FPGA实现非常的简单!
双击sim目录下的top_tb.bat文件,完成自动化的仿真。
在modelsim中直接看波形,可以看到wave_out输出的是余弦波,开始的频率是1MHz,后面随着频率控制字的增大,wave_out输出的频率也越来越高。
看看后面的仿真,当频率控制字增大到一定程度,一个周期从ROM中取得点就少了,波形失真严重!所以设计dds一定要明确输出波形的频率范围,合理选择相关的参数!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。