DDS(Direct Digital Synthesis)
1. DDS概述
直接数字合成(Direct Digital Synthesis, DDS)是一种通过数字方式生成模拟信号的技术,尤其适用于高精度、可调频率的信号生成。DDS技术通过数字电路合成出频率可调的波形,通常用于生成正弦波、方波、三角波等周期性信号。
DDS技术的核心优势在于其高精度和灵活的频率调节,广泛应用于频率合成器、信号发生器、通信系统等领域。
2. DDS的工作原理
DDS的工作原理基于相位累加器和**查找表(LUT)**的结合。其主要过程可以分为以下几个步骤:
-
频率控制字(Fword):频率控制字决定了信号的频率。该值会被用作相位累加器的增量,控制相位的变化速率。频率控制字越大,相位变化越快,输出频率也越高。
-
相位累加器(Phase Accumulator):相位累加器根据频率控制字(Fword)每个时钟周期更新相位。相位累加器的增量是Fword的值,每次时钟周期都会加上该增量,生成一个递增的相位值。
-
查找表(LUT):相位累加器的输出值经过适当的处理后,用作查找表的地址。查找表通常存储波形的数据(例如正弦波、三角波等),通过查找表可以输出与相位值相对应的波形幅度。
-
输出波形:通过查找表得到的值会作为输出信号。DDS系统通过连续更新相位并查找表产生相应的波形值,从而实现高精度的信号合成。
3. DDS的组成部分
DDS通常由以下几个主要部分组成:
-
频率控制字(Fword):
用来控制输出信号的频率。通过改变Fword的值,DDS可以生成不同频率的信号。 -
相位累加器:
-
负责累加频率控制字(Fword),每次时钟周期更新相位。
-
输出的相位值通常是一个大整数,需要通过适当的位宽处理(例如,32位、64位)来增加相位的精度。
-
-
查找表(LUT):
-
存储波形的数据,例如正弦波、三角波、方波等。根据相位累加器的输出,查找表会提供对应的波形幅度。
-
查找表的大小和精度直接影响到DDS的波形质量和频率分辨率。
-
-
相位到幅度转换:
从查找表中读取相应的幅值后,通常会有一个幅度转换模块将数据输出为标准的电压信号,供后续电路使用。 -
数字/模拟转换器(DAC)(可选):
如果需要模拟输出信号,DDS输出的数字信号通常需要经过数字/模拟转换器(DAC)转换为模拟波形。
4.设计代码
module DDS_Module(
input Clk,
input Reset_n,
input [31:0] Fword, // 频率控制字
input [11:0] Pword, // 相位控制字
output [13:0] Data // 输出波形数据
);
// 频率控制字同步寄存器
reg [31:0] Fword_r;
always @(posedge Clk)
Fword_r <= Fword;
// 相位控制字同步寄存器
reg [11: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 [11:0] Rom_Addr;
assign Rom_Addr = Freq_ACC[31:20] + Pword_r;
//为什么使用高12位(Freq_ACC[31:20])作为查找表地址?(见下面解释)
// ROM(波形查找表)
blk_mem_gen_0 rom(
.clka(Clk),
.addra(Rom_Addr),
.douta(Data) // 输出波形数据
);
endmodule
注:
- 频率控制字(Fword)的意义:决定了波形的频率,控制相位累加器的增量大小。增大Fword会使频率变快,但可能降低精度,因为相位变化较为粗糙。减小Fword会使频率变慢,但提高精度,因为相位变化更加平滑。
设计难点:
为什么使用高12位(Freq_ACC[31:20]
)作为查找表地址?
assign Rom_Addr = Freq_ACC[31:20] + Pword_r;
这行代码是将相位累加器的高12位与相位控制字(Pword_r)相加,来生成查找表(ROM)的地址。这里使用相位累加器的高12位来计算查找表地址,主要是为了限制查找表的地址空间,并且通过这种方法实现高频率下的精度控制。
-
查找表的大小:查找表(LUT)通常用于存储波形的样本值。为了使查找表具有合理的大小(例如:4096个样本),我们将相位累加器的值映射到查找表的地址空间。一般来说,查找表的地址空间为一个较小的值,例如12位地址可以表示的地址范围是0到4095(共4096个地址)。这正好适合将相位累加器的部分高位映射到查找表的地址。
-
相位累加器的高位:相位累加器通常是一个很大的值(例如32位),它表示的是累积的相位值。由于查找表的地址空间有限(例如12位地址对应的地址空间最大为4096),我们只需要将相位累加器的高12位作为查找表的地址。相位累加器的低位部分(如
Freq_ACC[19:0]
)表示的是相位的细节,而查找表的地址计算仅需要相位的高位,以决定相位的周期性变化。 -
相位分辨率和查找表的精度:相位累加器的低位部分(
Freq_ACC[19:0]
)决定了波形的精度,因为它表示了细粒度的相位变化。通过细化低位部分的精度,可以使波形生成更平滑,尤其是在频率较低时。相位的高位部分(Freq_ACC[31:20]
)则决定了周期性变化,代表相位的大致位置。由于查找表大小的限制(通常是12位),只需要使用相位累加器的高12位来决定查找表的索引。
5.仿真验证代码
`timescale 1ns / 1ps
module DDS_Module_tb;
reg Clk;
reg Reset_n;
reg [31:0]FwordA,FwordB;
reg [11: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; //2^16
PwordA=0;
FwordB = 65536;
PwordB=1024;
#201;
Reset_n = 1;
#5000000;
FwordA = 65536 *1024; //2^26
FwordB = 65536 *1024;
PwordA=0;
PwordB=2048;
#1000000;
$stop;
end
endmodule
这里先是对频率控制字A和B进行了赋值(2^16),对相位控制字A赋值为0,所以偏移值就是0.对相位控制字赋值为1024,(深度是4096,即有4096个数据)所以意味着B的偏移量为1/4个周期,即为90 degrees。
在运行了一段时间后,再次对他们重新进行赋值。A,B的频率控制字都是2^26,根据频率控制字的含义,我们知道此时频率更快了,但是精度更小了。A的相位频移还是0,但是B的相位控制字设为了2048,即频移了1/2的周期(2048/4096)。
仿真波形:
初步来看,波形没有什么大问题。在第一段,B相较于A延迟了1/4个周期。
放大观察:
在后面这段波形中,B相较于A,延迟了180 degrees。这与理论相符。但是对于B来说,他的输出值不是连续的,进行了突变这可能是因为,在对B进行第二次赋值是改变了B的相位控制字,而A的相位控制字并没有改变所导致的。