一次笔者在做项目时,甲方要去输出输出0-500KHz方波,精度千分之一。按照一般对主时钟进行分频的方法实现,势必有分频系数不是整数的现象,导致精度达不到。故采用dds进行频率合成。dds输入主时钟是50MHz,量化位宽为32位,即采用2^32对50M进行量化,每一份的精度是非常的小,满足精度要求。
设计思路:dds输出的是正弦波,然后利用一个比较强对正弦波的过零点进行比较,得到一个同正弦波频率的一个方波,满足甲方要求。由于dds输出本身是有符号数据,正弦波的过零点正好是正负数据交替的时刻,我们判断数据大于0输出1,小于0输出0,解决了问题。
有上图可以看出波形的过零点正好是正负数据交替的时候。
要特别注意dds输出的是有符号数据,需要使用signed定义。
module dds_top
(
input clk ,
input rst ,
input wire s_axis_config_tvalid ,
input wire [31 : 0] s_axis_config_tdata ,
output signed [15:0] sin ,
output sin_vld,
output O_ttl
);
wire signed [15:0]r_sin;
wire r_sin_vld;
reg ttl;
assign sin = r_sin;
assign sin_vld=r_sin_vld;
dds dds_inst
(
.aclk(clk), // 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(r_sin_vld), // output wire m_axis_data_tvalid
.m_axis_data_tdata(r_sin) // output wire [15 : 0] m_axis_data_tdata
);
always@(posedge clk)begin
if(rst==1'b1)begin
ttl<=1'b0;
end
else if (r_sin>'sd0)begin
ttl<=1'b1;
end
else if (r_sin<'sd0)begin
ttl<=1'b0;
end
end
assign O_ttl=ttl;