??本文介绍如何使用DDS IP核实现连续相位二进制频移键控。输入比特速率1MHz,1 bit对应的载波为4MHz正弦信号,0 bit对应的载波为6MHz正弦信号,系统时钟频率50MHz。
1、Vivado的DDS IP核简介
??直接数字合成器(Direct Digital Synthesizer)是一种基于全数字技术,从相位概念出发直接合成所需波形的一种频率合成技术。基本原理是将一个周期的正弦波数据存在一个查找表内(上图T1),相位累加器按系统时钟(上图clk)的频率不断累加相位(上图的
Δ
θ
\Delta\theta
Δθ),相位累加器输出的查找表的地址也在不断累加,使查找表周期性输出正弦波的数据,将这些正弦波数据送到DAC和低通滤波器就能得到模拟正弦信号。 ??根据IP核的数据手册,DDS IP核输出频率
f
o
u
t
f_{out}
fout?为
f
o
u
t
=
f
c
l
k
Δ
θ
2
B
θ
f_{out}=\frac{f_{clk}\Delta\theta}{2^{B_\theta}}
fout?=2Bθ?fclk?Δθ?其中,
f
c
l
k
f_{clk}
fclk?是系统时钟(System Clock),
Δ
θ
\Delta\theta
Δθ为相位累加器累加的数值,
B
θ
B_\theta
Bθ?为相位累加器的位宽(Phase Width)。那么我们可以由所需的输出频率计算
Δ
θ
\Delta\theta
Δθ的值
Δ
θ
=
f
o
u
t
2
B
θ
f
c
l
k
\Delta\theta=\frac{f_{out}2^{B_\theta}}{f_{clk}}
Δθ=fclk?fout?2Bθ?? 相位累加器的位宽
B
θ
B_\theta
Bθ?由频率分辨率(Frequency Resolution)
Δ
f
\Delta f
Δf决定,公式为
B
θ
=
?
l
o
g
2
(
f
c
l
k
Δ
f
)
?
B_\theta=\lceil log_2(\frac{f_{clk}}{\Delta f})\rceil
Bθ?=?log2?(Δffclk??)?输出位宽由Spurious Free Dynamic Range和Noise Shaping决定,它们的关系见下表 ??由DDS相位累加的工作原理可知,DDS输出的信号在频率改变时依然能保持连续相位。
2、配置DDS IP核
??2.1 新建一个Vivado工程,点击Flow Navigator中的IP Catalog,选择DDS Compiler(几个蓝色背景的IP核是同一个),打开DDS IP核的配置窗口。
??2.2 按下图配IP核 ??根据前一节介绍的公式,可以算得SFDR设置成84dB,输出位宽为14bit,频率分辨率设置为1Hz,Phase Width为26bit。 ??Summary显示了IP核的配置信息。 ??2.3 接口介绍
- aclk:时钟引脚,工程中输入50MHz时钟信号;
- s_axis_phase_tdata:
Δ
θ
\Delta\theta
Δθ的值从这里输入,只有低26bit有效;
- s_axis_phase_tvalid:1 表示s_axis_phase_tdata输入的采样数据有效,一直拉高;
- m_axis_data_tdata:输出正弦波的数据;
- m_axis_data_tvalid:1 表示m_axis_data_tdata输出的数据有效。
3、编写Verilog代码例化DDS IP核
??4MHz载波的累加相位
Δ
θ
\Delta\theta
Δθ为
Δ
θ
=
4
×
2
26
50
=
5368709.12
≈
5368709
\begin{aligned} \Delta\theta=& \frac{4\times 2^{26}}{50} \\ =& 5368709.12 \\ \approx& 5368709 \end{aligned}
Δθ==≈?504×226?5368709.125368709?6MHz载波的累加相位
Δ
θ
\Delta\theta
Δθ为
Δ
θ
=
6
×
2
26
50
=
8053063.68
≈
8053064
\begin{aligned} \Delta\theta=& \frac{6\times 2^{26}}{50} \\ =& 8053063.68 \\ \approx& 8053064 \end{aligned}
Δθ==≈?506×226?8053063.688053064?
module FskMod(
input resetn,
input clk,
input din,
output signed [14:0] dout
);
wire s_axis_phase_tvalid;
wire [31:0] s_axis_phase_tdata;
wire [15:0] m_axis_data_tdata;
assign s_axis_phase_tvalid = resetn;
assign s_axis_phase_tdata = din?32'd5368709:32'd8053064;
dds_2fsk u2 (
.aclk(clk),
.s_axis_phase_tvalid(s_axis_phase_tvalid),
.s_axis_phase_tdata(s_axis_phase_tdata),
.m_axis_data_tvalid(),
.m_axis_data_tdata(m_axis_data_tdata)
);
assign dout = m_axis_data_tdata[14:0];
endmodule
??如果IP核的Phase Increment Programmability选成了Programmable可以参考被注释的代码。
4、编写test bench文件
??test bench文件的功能是生成复位信号、50MHz的时钟信号、数据比特信号等。系统时钟频率为50MHz,输入比特速率1MHz。
module tb_FskMod();
parameter LEN = 10000;
reg clk;
reg resetn;
reg din;
wire [14:0] dout;
reg code[LEN-1:0];
initial begin
clk = 1'b0;
resetn = 1'b0;
din = 1'b0;
$readmemh("code1.txt", code);
#1000
resetn = 1'b1;
fskmod;
end
always #10 clk = ~clk;
integer k;
task fskmod;
begin
for(k = 0; k < LEN; k = k+1)
#1000 din = code[k];
end
endtask
FskMod u1(
.resetn(resetn),
.clk(clk),
.din(din),
.dout(dout)
);
endmodule
5、功能仿真
??仿真结果如下:
|