这周六看了Xilinx的 DDS手册学了下DDS的使用,目标是可编程生成任意频率的正弦波。
大二下没啥英语课,看这英文手册怪费劲的(就算有估计看着也费劲),有误或者表达不准确的欢迎指正。
标准operation模式下,输出频率频率=已知时钟频率*频率控制字(相位增量)/2^相位累加器位宽。
rasterized模式下,把分母换成可直接调控的M,方便输出一些整数频率波形。
相位累加器位宽为16,输出位宽为8,采用hardware parameters模式
频率控制字PINC(相位增量)和相位控制字POFF(相位便宜量)都选择为可编程模式。
Phase Angle Increment Values 和Phase Angle Offset Values 为频率控制字和相位控制字初始值设定。
可以从summary上看到一些配置情况
additional summary可以看到输出波形的预设频率和相位偏移
频率=PINC*fclk/2^phase width=53687乘100/2的16次方=81.919MHz
相位偏移为=2的15次方/2的16次方 个周期
创建完毕后,可在如下位置找到例化用的代码直接复制粘贴到top里
dds_compiler_0 your_instance_name (
.aclk(aclk), // input wire aclk
.s_axis_config_tvalid(s_axis_config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tdata(s_axis_config_tdata), // input wire [31 : 0] s_axis_config_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata(m_axis_data_tdata), // output wire [15 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata) // output wire [15 : 0] m_axis_phase_tdata
);
介绍几个关键的参数(个人理解):
s_axis_config_tvalid:相当于一个配置通道的使能信号,高电平有效
s_axis_config_tdata:高16位用于储存相位信息(偏移的相位=2p*此值除以2^相位累加器位宽),后16位为频率控制字
m_axis_data_tvalid:输出有效信号吧TVALID for output DATA channel
m_axis_data_tdata:输出信号,高位是正弦,低位是余弦
m_axis_phase_tvalid:输出有效标志TVALID for output PHASE channel
m_axis_phase_tdata:输出相位通道
module dds001(
input clk,
input config_tvalid,//使能
input rst_n,
input [15:0] config_data_poff,config_data_pinc,//频率和相位控制字
output [7:0] dds_data_sin_0,dds_data_cos_0
);
wire m_axis_data_tvalid;
wire m_axis_phase_tvalid;
wire [15:0]m_axis_phase_tdata;
dds_compiler_0 dds_init (
.aclk(clk), // input wire aclk
.s_axis_config_tvalid(config_tvalid), // input wire s_axis_config_tvalid
.s_axis_config_tdata({16'd0,config_data_pinc}), // input wire [31 : 0] s_axis_config_tdata
.m_axis_data_tvalid(m_axis_data_tvalid), // output wire m_axis_data_tvalid
.m_axis_data_tdata({ dds_data_sin_0,dds_data_cos_0}), // output wire [15 : 0] m_axis_data_tdata
.m_axis_phase_tvalid(m_axis_phase_tvalid), // output wire m_axis_phase_tvalid
.m_axis_phase_tdata(m_axis_phase_tdata) // output wire [15 : 0] m_axis_phase_tdata
);
endmodule
贴上代码
module tb_dds(
);
reg clk;
always #5 clk<=~clk;
reg rst_n;
wire [7:0] dds_data_sin_0,dds_data_cos_0;
reg [15:0] config_data_pinc,config_data_poff;
reg config_tvalid;
dds001 dds_001_Init
(
.clk(clk),
.rst_n(rst_n),
.dds_data_sin_0(dds_data_sin_0),
.dds_data_cos_0(dds_data_cos_0),
.config_data_poff(config_data_poff),
.config_data_pinc(config_data_pinc),
.config_tvalid(config_tvalid)
);
initial
begin
clk = 0;
rst_n = 1;
config_data_poff = 16'h4000;
config_data_pinc = 16'd66;
config_tvalid = 1'b1;
#100000
config_data_pinc = 16'd666;
#100000
config_data_poff = 16'h8000;
$stop;
end
endmodule