DDS简介
直接数字式频率合成器(Direct Digital Synthesizer)
在参考频率时钟的驱动下,DDS模块开始工作;当每来一个参考时钟时,累加器就把频率控制字FW与寄存器输出的值进行累加,将相加后的结果再输入到寄存器中,而累加寄存器就将在上一个参考时钟作用时产生的数据通过反馈的方式输送到累加器中。这样,在时钟的作用下,就可以不停的对频率控制字进行累加。此时,用相位累加器输出的数据作为地址在波形存储器中通过查找地址所对应的幅值表,就可以完成其从相位到幅值之间的转化。
相位累加器 Phase = Phase + fre_word,可以暂且理解为i = i + 1一样的东西。
频率控制字 fre_word,这个东西的值直接影响输出信号的频率。
D
D
S
核
频
率
分
辨
率
:
f
out?
=
f
c
l
k
2
B
θ
(
n
)
Δ
θ
DDS核频率分辨率 : f_{\text {out }}=\frac{f_{c l k} }{2^{B_{\theta(n)}}}\Delta \theta
DDS核频率分辨率:fout??=2Bθ(n)?fclk??Δθ 其中Δθ:频率控制字,取值后文用fre_word表示。
B
θ
(
n
)
B_{θ(n)}
Bθ(n)?:相位累加器位宽,后文用B表示。fclk:DDS工作时钟。频率分辨率就是当Δθ=1时的fout。
在参考信号与加法器或寄存器的位数给定时,信号最终的输出频率主要由频率控制字决定。故当频率控制字变化时,输出频率也跟着变化,从而可以实现调频的基本功能。
先假如我们需要的信号频率范围:1M-10MHz,分辨率10KHz。 取Δθ=1,fout=0.01MHz,B=10bit,我们可得DDS工作时钟fclk=10.24MHz。
同理1KHz-8.192MHz,分辨率1KHz。 取Δθ=1,fout=1KHz,B=13bit,我们可得DDS工作时钟fclk=8.192MHz。
即产生一个正弦波信号需要2部分: 1. 时钟分频器 2. DDS IP核
时钟设置
IP Catalog->Clocking Wizard Input Frequency 50MHz (根据自己板子选) Output Clocks根据需求输出10.24MHz和8.192MHz
DDS设置
IP Catalog->DDS Compiler->Component Name 这个做的比较简单,暂时不对相位做出要求
13位的DDS设置方法类似,最终Summary大概是这样:
频率叠加
本质:有符号数相加
测试代码
部分程序
/*************************************************************************
PLL IP calling
**************************************************************************/
clk_wiz_0 clk_wiz_0_inst
(// Clock in ports
.clk_in1 (sys_clk ), // IN 50Mhz
// Clock out ports
.clk_out1 (CLK_10240K ), // OUT 200Mhz
.clk_out2 (CLK_8192K ), // OUT 200Mhz
// Status and control signals
.reset (~rst_n ), // RESET IN
.locked (locked )
);
/*************************************************************************
DDS IP calling
**************************************************************************/
DDS_10KHZ DDS_10_inst (
.aclk(CLK_10240K ), // input wire aclk
.s_axis_config_tvalid( fre_word_en ), // input wire s_axis_config_tvalid
.s_axis_config_tdata( fre_word_10 ), // input wire [15 : 0] s_axis_config_tdata
.m_axis_data_tvalid(m_axis_data_tvalid10), // output wire m_axis_data_tvalid
.m_axis_data_tdata( rdata_10 ) // output wire [7 : 0] m_axis_data_tdata
);
DDS_1KHz DDS_13_inst (
.aclk(CLK_8192K ), // input wire aclk
.s_axis_config_tvalid( fre_word_en ), // input wire s_axis_config_tvalid
.s_axis_config_tdata( fre_word_13 ), // input wire [15 : 0] s_axis_config_tdata
.m_axis_data_tvalid(m_axis_data_tvalid13), // output wire m_axis_data_tvalid
.m_axis_data_tdata( rdata_13 ) // output wire [7 : 0] m_axis_data_tdata
);
/*************************************************************************
Multi-frequency add
**************************************************************************/
// 由于最高位存在符号位,因此不能直接叠加
// 相当于加一个有符号数的加法
always@(posedge sys_clk)
begin
rrdata_10 <= { rdata_10[7],rdata_10[7:0]};
rrdata_13 <= { rdata_13[7],rdata_13[7:0]};
rdata_add = rrdata_13+ rrdata_10 ;
end
assign data_add = rdata_add ;
部分仿真程序
pll_test uut (
.sys_clk(sys_clk),
.rst_n(rst_n),
.clk_out(clk_out),
.fw_10(fw_10),
.fw_13(fw_13),
.data_10(data_10),
.data_13(data_13),
.data_add(data_add)
);
initial begin
// Initialize Inputs
sys_clk = 0;
rst_n = 0;
fw_10 = 10'b00_0000_0001;
fw_13 = 10'b0_0000_0000_0001;
// Wait 100 ns for global reset to finish
#100;
rst_n = 1;
// Add stimulus here
#20000;
// $stop;
end
仿真结果查看
波形设置:右键单击
MATLAB验证
f1=110^3; %1KHz
f2=1010^3; %10KHz
y1 = sin(2pif1.t);
y2 = sin(2pif2.t);
y = sin(2pif1.t)+sin(2pi*f2.*t);
参考网页
1.FPGA学习(一)——产生频率可控的正弦波 2.Vivado DDS IP配置与仿真(1)正弦、余弦信号发生器
附:本文程序下载链接
|