DDS Compiler
设计原理
一个正弦波的幅度不是随时间线性变化的,但是相位是时间的线性函数。因此可以考虑用一个线性递增的变量存储相位,再将相位转换成相应的正弦波幅度。

首先存储一个周期的正弦波,然后将相位用比特量化,即平均分成份,以的频率每始终周期转动,则可以得到输出频率为的信号,
可以看出,输出频率是参考时钟频率、相位量化位宽、和相位增量(频率控制字)的函数。增加频率控制字,将得到更高频率的信号。
根据奈奎斯特采样定律,为了使波形不失真,需要满足,则有
始终小于,不妨将其看成是一个分频器,通过修改频率控制字分频参考时钟,获得所需要的频率。
组成结构

如图,直接式数字频率合成器(Direct Digital Synthesizer,DDS)主要由相位累加器、波形查找表、数模转换器和低通滤波器等部分组成。
其中的核心部分是相位累加器,由一个位累加器和位寄存器构成,在每个参考时钟上升沿,累加器将频率控制字与累加寄存器的输出相加,结果作为寄存器新的输入。如此反复, 当累加器累加满时, 就会发生溢出,完成一个周期, 即DDS合成信号的一个频率周期。
波形查找表(Lookup Table,LUT)中存储了正弦波的数字幅度信息,每个地址对应一个相位点,每个相位点对应正弦波的一个幅度值。将相位累加寄存器的输出与相位控制字相加,作为波形查找表的输入地址,地址映射为正弦波幅度,输出到D/A转换器。
D/A转换器将数字信号转换成模拟信号,再经低通滤波器滤除不需要的取样分量,最终得到所需信号。
量化性能
理想的DDS应满足:
相位累加器的输出相位为,周期,则波形查找表输出的幅度序列为 经过D/A转换器后 令,是的理想采样信号,令。
则有的频谱是的频谱以为周期的延拓,得到的频谱即理想的DDS输出频谱为 由输出频谱的表达式可以看出,它的谱线分布在处,即DDS输出信号频谱的镜像分量总是在参考频率的附近。因此,理想条件下,在MATLAB绘制的的功率谱密度图像中不应该存在其它的频率分量,如图(左)所示

DDS的量化性能分析
DDS的幅度量化误差
相位对应的幅度值是小数时,波形查找表不能够精确的存储,导致幅度的量化误差,DDS输出的信号是周期性的,这种误差也具有周期性,体现在频谱上是周期性的频率分量。
为探究DDS幅度的量化误差对载波信号的影响,设定采样频率为160MHz,载波频率为21MHz,幅度的量化位数分别为8位和16位,得到的载波功率谱密度如上图(左、右)所示,右图对应的量化位数为8位,量化误差较大,因此存在很多高频分量,左图对应的量化位数为16位,精度较高,几乎没有高频分量。
DDS的相位截断误差
频率分辨率不可能无穷小,可能是小数,用二进整数表示时小数位要被去掉,造成误差;波形查找表的位数有限,会带来幅度量化误差;相位累加器的位数有限,则相位值会被截断,导致相位不连续和周期性误差,会在输出频谱中产生杂散。
控制变量“幅度的量化位数”8位不变,改变相位量化位宽,得到功率谱密度图像如图所示,上图对应的相位量化位宽为16位,右图对应的相位量化位宽为32位。

DDS的量化性能分析
DDS的配置中用二进制整数表示频率控制字。由频率控制字的计算公式可知,当参考频率为,输出频率为,相位量化位宽数为16或32时,需要的频率控制字不是整数,因此会带来相位截断误差。体现在频谱上,是信号频谱的杂散分量,随着相位量化位数增加,频率分辨率和相位精度提高,减少了因为相位截断造成的上图的杂散谱线
与PLL相比:
DDS的频率分辨率高,可以生成多种波形;在高频段由较多的杂散分量
PLL输出频率更稳定,相位噪声更低
MATLAB仿真
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| close all; clear; clc;
tic;
fs = 160e3; f_out = 10e3; phase_width = 16; N = 2 ^ phase_width; output_width = 16; phase_offset = 0; phase_increment = f_out * N / fs;
n = 0 : 1/N : 1/4 - 1/N; cos_rom = cos(2 * pi * n); len_lut = length(cos_rom);
figure; stem(cos_rom(1:len_lut)); xlabel("Points"); ylabel("Amplitude"); xlim([0, len_lut]); ylim([0, 1]); title("Look-up Table (1/4 cos)"); grid on;
t_total = 1; t = 0 : 1/fs : t_total - 1/fs; dds_dout_len = length(t);
dds_dout = zeros(1, dds_dout_len); phase_acc = phase_offset;
for i = 1:dds_dout_len idx = floor(mod(phase_acc, N)); if idx == 0 dds_dout(i) = 1; elseif idx > 0 && idx <= len_lut idx_new = idx; dds_dout(i) = 1 * cos_rom(idx_new); elseif idx > len_lut && idx <= len_lut * 2 idx_new = 2 * len_lut + 1 - idx; dds_dout(i) = -1 * cos_rom(idx_new); elseif idx > len_lut * 2 && idx <= len_lut * 3 idx_new = idx - 2 * len_lut; dds_dout(i) = -1 * cos_rom(idx_new); else idx_new = 4 * len_lut + 1 - idx; dds_dout(i) = 1 * cos_rom(idx_new); end phase_acc = phase_acc + phase_increment; end
dds_dout = floor(dds_dout / max(dds_dout) * 2 ^ (output_width - 1));
figure; subplot(2, 1, 1); plot(t(1:2048), dds_dout(1:2048)); xlabel('Time (s)'); ylabel('Amplitude'); title('DDS Generated Signal'); grid on; subplot(2, 1, 2); pwelch(dds_dout);
sgtitle("Simulation of the Quantization Performance of DDS");
toc;
|
IP Catalog配置
详见Euler0525@Wiki/zynq/DDS Compiler
参考资料