DDS基本原理与FPGA实现
一.DDS基本原理
DDS(Direct Digital Synthesizer)即数字合成器,是一种新型的频率合成技术,具有相对带宽大,频率转换时间短、分辨率高和相位连续性好等优点。较容易实现频率、相位以及幅度的数控调制,广泛应用于通信领域。
DDS 的基本结构主要由相位累加器、相位调制器、波形数据表 ROM、D/A转换器等四大结构组成,其中较多设计还会在数模转换器之后增加一个低通滤波器。DDS 结构示意图见下图
先对其中各参数做一下说明。系统时钟 CLK 为整个系统的工作时钟,频率为 f_CLK;频率字输入 F_WORD,一般为整数,数值大小控制输出信号的频率大小,数值越大输出信号频率越高,反之,输出信号频率越低;相位字输入P_WORD,为整数,数值大小控制输出信号的相位偏移,主要用于相位的信号调制;设输出信号为 CLK_OUT,频率为 f_OUT。
这里相位累加器位数为N位(N的取值范围实际应用中一般为24~32),相当于把正弦信号在相位上的精度定义为N位。
1.频率控制
f
O
U
T
=
F
w
o
r
d
×
F
c
l
k
2
N
f_{OUT}=F_{word}\times \frac{F_{clk}}{2^N}
fOUT=Fword×2NFclk
关于这个公式该如何理解,我们通过下面的例子来掌握。
下图为一个完整周期的正弦信号的波形,总共有33个采样点,其中第1点和第33点的值相同,第33点为下一个周期的起始点,因此,实际一个周期为32个采样点(1~32)。
现在有以下几种输出情况:
<1>当使用FPGA控制DAC输出一个周期的正弦信号时,每1ms输出一个数值。如果每个点都输出,则总共输出这一个完整的周期信号需要输出32点,因此输出一个完整的信号需要32ms,可知输出信号的频率为1000/32 Hz。这里Fclk = 1000Hz(周期是1ms),Fo = 1000/32 (2^N N=5)
<2>如果需要用这一组数据来输出一个2*(1000/32)Hz的正弦信号,因为输出信号频率为2*(1000/32)Hz,那么输出一个完整的周期的正弦波所需要的时间为32/2,即16ms。因为FPGA控制DAC输出信号的频率固定为1ms,所以我们选择隔点输出,输出(1、3、5、7……29、31)这些点,因为采用这些点,我们还是能够组成一个完整的周期的正弦信号,而输出时间缩短为一半,即频率提高了一倍。这里Fclk = 1000Hz(周期是1ms),Fo =2*1000/32 (2^N N=5),F_WORD=2。
2.相位控制
对于相位的调整,则更加简单。只需要在每个取样点的序号上加上一个偏移量,便可实现相位的控制。例如,上面默认的是第1ms时输出第一个点的数据,假如我们现在在第1ms时从第9个点开始输出,则将相位左移了90度,这就是控制相位的原理。
实现DDS输出时,将横坐标上的数据作为ROM的地址,纵坐标上的数据作为ROM的输出,那么指定不同的地址就可实现对应值的输出。而我们DDS输出控制频率和相位,归结到底就是控制ROM的地址。
二.模块功能设计
在本设计中参考时钟F_clk频率为50 MHz,相位累加器位数取32位,相位控制字位数取12位,由于自用DAC模块要求14位,所以Data取14位。
1.设计代码
先配置ROM IP核
这里配置的是块ROM ,可参考我前一篇文章:IP核的使用之ROM(Vivado)文章来源:https://www.toymoban.com/news/detail-734571.html
module DDS_Module(
Clk,
Reset_n,
Fword,
Pword,
Data
);
input Clk;
input Reset_n;
input [31:0] Fword;
input [12:0] Pword;
output [13:0] Data; //这里14位是因为我后续使用的DAC模块为14位
//频率控制字同步寄存器
reg [31:0] Fword_r;
always@(posedge Clk)
Fword_r <= Fword;
//相位控制字同步寄存器
reg [12:0] Pword_r;
always@(posedge Clk)
Pword_r <= Pword;
//相位累加器
reg [31:0] Freq_ACC;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Freq_ACC <= 0;
else
Freq_ACC <= Fword_r + Freq_ACC;
//波形数据表地址
wire [12:0] ROM_Addr;
assign ROM_Addr = Freq_ACC[31:20] + Pword_r;
blk_mem_ROM rom(
.clka(Clk),
.addra(ROM_Addr),
.douta(Data)
);
endmodule
2.激励仿真
`timescale 1ns / 1ns
module DDS_Module_tb;
reg Clk;
reg Reset_n;
reg [31:0]FwordA,FwordB;
reg [12:0]PwordA,PwordB;
wire [13:0]DataA,DataB;
DDS_Module DDS_ModuleA(
Clk,
Reset_n,
FwordA,
PwordA,
DataA
);
DDS_Module DDS_ModuleB(
Clk,
Reset_n,
FwordB,
PwordB,
DataB
);
initial Clk = 1;
always #10 Clk = ~Clk;
initial begin
Reset_n = 0;
FwordA = 65536;
PwordA=0;
FwordB = 65536;
PwordB=1024;
#201;
Reset_n = 1;
#5_000_000;
FwordA = 65536 *1024;
FwordB = 65536 *1024;
PwordA=0;
PwordB=2048;
#1_000_000;
$stop;
end
endmodule
3.仿真结果
根据公式得到:
f
o
u
t
=
F
w
o
r
d
×
F
c
l
k
2
N
=
65536
×
50
×
1
0
6
2
32
=
762.939
H
z
f_{out}=F_{word}\times \frac{F_{clk}}{2^N}=65536\times \frac{50\times 10^6}{2^{32}}=762.939\,\,Hz
fout=Fword×2NFclk=65536×23250×106=762.939Hz
与仿真结果图中周期时间取对数得到的值一样,故可验证结果正确。文章来源地址https://www.toymoban.com/news/detail-734571.html
到了这里,关于【边学边记_11】——DDS基本原理与FPGA实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!