DDS设计
文章目录
RTL设计
DDS核心代码
module dds_core_sin(
CLK , // clock, posedge valid
RST , // reset, high level reset
FWEN , // frequency word update enable, high level enable
FWIN , // input frequency word
CLKOUT, // output clock
SINOUT); // sine signal output, 2's complement format
input CLK;
input RST;
input FWEN;
input [32-1:0] FWIN;
output[12-1:0] SINOUT;
output CLKOUT;
parameter FW_WL = 32; // frequency word word length in bit
parameter RA_WL = 10; // rom address word length in bit
parameter RD_WL = 12; // rom data word word length in bit
reg [FW_WL -1:0] fwin_R; // freq word DFF
reg [FW_WL -1:0] acc_R; // phase ACC DFF
reg [RA_WL -1:0] addr_R; // rom address DFF
reg [RD_WL -1:0] sinout_R; // sin wave output DFF
wire [RD_WL -1:0] romout_W; // rom data output wire
always @ (posedge CLK or posedge RST) begin
if(RST) begin
fwin_R <= 0;
acc_R <= 0;
addr_R <= 0;
sinout_R <= 0;
end
else begin
// update fwin_R DFF
if(FWEN)
fwin_R <= #1 FWIN;
else
fwin_R <= #1 fwin_R;
// update acc_R
acc_R <= #1 fwin_R + acc_R;
// update addr_R, the acc_R high RA_WL is rom address
addr_R <= acc_R[FW_WL-1:FW_WL-1-(RA_WL-1)];
// update output DFF
sinout_R <= #1 romout_W;
end
end
DDS_CORE_ROM u_sinrom(
.CLK (CLK ), // clock
.RA (addr_R ), // read address
.RD (romout_W )); // read data
assign SINOUT = sinout_R;
assign CLKOUT = CLK;
endmodule // module dds_core
本设计加入了额外的D触发器流水线以减小ROM的I/O延迟带来的影响。
#表延迟。
#1 a=1;延迟一个时间单位后执行a=1;语句。
RTL视图验证

如图,代码中的#1被编译成D触发器,在电路结构中即为流水线结构。
波形仿真验证

输出为正弦波采样点序列,近似正弦波。
波形渣是因为流水线的输出不同时导致的,即之前的实验中分析过的不同通道输出不同步产生的毛刺。在仿真这里只要看一下大致的波形就可以了,实际还要看SignalTap采集的信号或者示波器显示。
问题总结
CLK频率、频率字与输出波形的频率
如何根据CLK频率和输入的频率字来设定输出波形的频率?
设输出正弦波频率为 f 1 f_1 f1,电路系统时钟为 f s y s = 50 f_{sys}=50 fsys=50MHz, 计数器步进增量为 CNT,计数器位宽为n。
由上文可以得知:ROM中128个存储空间存储着sin的一个周期128个采样点的值。计数最大值为
2
n
2^n
2n,遍历一遍会输出
2
n
C
N
T
\frac{2^n}{CNT}
CNT2n个点,需要
2
n
C
N
T
\frac{2^n}{CNT}
CNT2n个时钟周期,生成信号的一个周期对应
2
n
C
N
T
\frac{2^n}{CNT}
CNT2n个时钟信号周期,所以生成的信号频率就是clk时钟频率的
2
n
C
N
T
\frac{2^n}{CNT}
CNT2n分之一。即:
f
1
=
f
s
y
s
×
C
N
T
2
n
f_1=f_{sys}\times\frac{CNT}{2^n}
f1=fsys×2nCNT
当取CNT为1时,可得最低的输出波形频率为:
f
1
m
a
x
=
f
s
y
s
2
n
f_{1_{max}}=\frac{f_{sys}}{2^n}
f1max=2nfsys
如果需要更低的频率,那么可以提高计数器位宽n并对数据进行截断,取高位送入ROM。这样就可以提高n,从而降低输出波形的频率。
补码与DAC,仿真工具的数据类型
补码格式能够直接送给DAC吗?
有符号数的补码要将最高位取反后送入DAC。有符号数的补码正数符号位为0,负数符号位为1。其他位正数为2进制,负数为2进制取反加1。将最高位取反之后正好是从小到大映射到无符号数范围内,即可实现生成无符号数的正弦波。如图,这里代表的仅仅是电平的相对值,实际输出还要看DAC芯片是否有直流偏置、基准电压等。

仿真工具里在数据类型中有多种选项,可以根据需要选择自己想要查看的数据类型。
波表ROM的Verilog代码生成
波表ROM的Verilog代码太长了,如何快速完成ROM的代码?
可以使用matlab或其他编程工具编程输出。
ROM参数调节
如何调节ROM的空间地址容量和数据字长?调节这些参数有什么意义和代价?
调节地址容量:更改RA_WL,RA_WL为ROM地址数据长度。降低地址容量会使能生成的最低频率升高,但ROM所需的存储空间也变少。增加地址容量可以生成更低频率的信号。但增加地址容量如果超过了目前ROM的存储范围,就需要扩充ROM的存储值,就需要更长的代码和更多的存储空间。
调节数据字长:更改RD_WL,RD_WL为ROM输出数据长度。增加字长则会提高精度,但需要更多的端口,如果字长超过了目前ROM的存储字长则需要提高ROM存储值的精度,同时也要求更多的存储空间。缩短字长会降低精度,但也减少了对端口的使用量。
输出波形
如何评价输出波形的质量?
可以通过示波器进行观察,也可以通过matlab进行波形频谱的分析。频谱分析在下面将会继续展开说明。
开发板测试
SignalTap采样测试
使用按键来控制频率字的改变。
设定频率的UP和DOWN按键,让DDS轮流输出1MHz,2MHz,…10MHz的时域波形。
使用Quartus的Signal TAP 观察DDS的输出波形,注意要调节Signal TAP的观察格式为“有符号数的曲线”模式。
频率为1MHz时:

频率为6MHz时:

频率10MHz时:

三个曲线虽然都有不同程度的失真,但都是对应所要生成的频率分量幅度最高,经过DAC和滤波滤去其他分量之后生成的模拟信号效果就会很好了。下面是频谱幅度分析。
matlab频谱分析
采样数据的保存
首先导出 Signal TAP 的捕获数据至电脑,生成List文件。

右键采集到的数据,选择Create SignalTap II List File,导出数据文件。

复制采样点数据。新建Excel,粘贴,上方选择数据栏,然后选择分列,并选择固定宽度分列。

选择采样点的十进制数据,复制数据保存并到matlab里进行频谱分析。
频谱分析函数属matlab编程,不再赘述。
频谱分析
频谱分析结果如图:

可见:在每个图中,所要生成的频率分量幅度都是最高的。其他频率分量都有至少50dB的衰减,信号底噪在-100dB左右。鉴于我在数字信号处理课程中学习设计的滤波器阻带衰减均在四五十dB左右,所以这个频谱纯度还可以吧。
本文详细阐述DDS设计的核心模块dds_core_sin,包括RTL设计中的频率字处理、DFF流水线与ROM操作。讲解了如何根据CLK频率调整输出波形频率,并讨论了补码与DAC的关系,以及如何利用MATLAB进行波表ROM生成和参数调节。最后介绍了开发板测试和频谱分析方法,以评估输出波形质量。
1307

被折叠的 条评论
为什么被折叠?



