基于FPGA的DDS实现原理

嗯。。。最近画了个FPGA开发板练练手。。。希望一切的努力最后都能有所收获吧。

DDS Direct Digital Synthesis,即直接数字合成器,可以用来生成频率范围很宽的各种波形。其原理图如下所示:

比较重要的两个参数是相位控制字和频率控制字,一个用来控制初相位,一个来控制频率。那么这是如何做到的呢

我们假设有一个基波,它一个周期有64个采样点,那么怎么把它的频率变成两倍呢?由于采样的周期不变,那么如果采样点是原来的一半不就可以了。那么根据采样原理,假如原理采样点分别是1,2,3.。。。64.那么要想使得频率增加一倍,我们的采样点就得变成1,3,5,。。。63 这样相同的时间可以采集两倍的波形还能最大程度保持波形的完整。显然要想使它频率变成4倍,采样点变成1,5,9,。。。61 更高频率的可以类推。那么要使它频率变成原来的一半呢?很简单,只要采样点变成1,1,2,2,3,3,。。。,64,64即可。

那么频率控制字是如何做到的呢?其实和累加器原理差不多。还是以这个例子为例,加入我们要生成这个64个采样点的基波,常规做法是不是生成一个ROM,然后随着时钟信号的边沿去访问ROM。很一般的做法:

reg [5:0] count;
always@(posedge clk)
    count<=count+1'b1;

通过count寄存器作为地址去遍历ROM,那么两倍呢?是不是地址只要跳着就行

reg [5:0] count;
always@(posedge clk)
    count<=count+2'd2;//频率加倍

同理,对于倍速更高的类似就行,但是这么做并不通用,加入我要降低频率怎么办,我还得加个计数器。有什么办法可以两者兼得呢?很简单,增加位宽。

假设现在位宽增加到了8位,我们取高6位作为值,那么频率控制字怎么作用呢 下面代码分别展示了两倍频和0.5倍频的例子:

reg [7:0] count;
always@(posedge clk)
    count<=count+4'b1000;//2倍频

reg [5:0] real_count;
assign real_count=count[5:0];





reg [7:0] count;
always@(posedge clk)
    count<=count+4'b0010;//0.5倍频

reg [5:0] real_count;
assign real_count=count[5:0];

是不是很完美。。。其实原理很简单,两倍频其实还是和我们常规想法一样+2.但是由于位宽的拓展以及最终我们取高6位,那么对于倍频来说后两位根本没有用,所以原来是2'b10变成了现在的4'b10_00,那么增加的位宽干嘛的呢?不就用来降低频率的吗?原来如果是基波的话,我只要每个时钟沿使得[7:0]count的第3位加一即可,但是现在对于0.5倍频,每个时钟沿加2'10不就是相当于每两个时钟周期[5:0]count的数据变化一次吗。

那么频率控制字了解了,相位控制字就很好理解了,对于任意一个三角函数 y=sin(2*π*w*t+b) 我们之前相位控制字的累加不就相当于当前时刻的相位吗?那么总相位是不是还要加上初相位b不就行了。

那么位宽选择多少合适,看你的具有需求了。需要多少范围的频带。

下面给出简单仿真:分别是基波,2倍频,0.5倍频

2倍频,且初相位为波峰

0.25倍频,且初相位为波谷

大家看一下时间是不是可以对得上呢?这里我目测的肯定多少有点偏差,但是差不多哈。另外数据点的生成我用c++做的。一般建议MATLAB。实际差不多。

最后附上vivado下coe文件的格式

数据用“,”最后结尾用“;”

最后希望有相同方向的小伙伴多多交流哈,博主今年秋招了,希望能有个好结果吧。

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值