DDS IP实现啁啾信号

简介

DDS(Direct Digital Synthesizer)即数字合成器,是一种新型的频率合成技术,具有低成本、低功耗、高分辨率、频率转换时间短、相位连续性好等优点,对数字信号处理及其硬件实现有着很重要的作用。DDS 的基本结构主要由相位累加器、相位调制器、波形数据表 ROM、D/A 转换器等四大结构组成。本章节主要介绍的是XILINX IP DDS的使用。

DDS的原理

相位累加器

相位累加器是一种模 N 计数器,具有 2N 个数字状态,这些状态会在每个系统时钟输入脉冲发生时逐渐递增。增量的大小取决于应用于累加器相加级的调谐字 M 的值。该调谐字确定了计数器增量的步长。这将决定输出波形的频率。

相位累加器的长度通常为 24 - 48 位;24 位累加器共有 224(即 16,777,216)个状态。这一数字表示 0 到 2p 弧度之间的相位值数量,或者说是可实现的相位增量。对于 24 位相位累加器,相位分辨率为 3.74 E-7 弧度。如果使用更大的相位累加器,相位增量会变得更加精细。如下图所示:

关于DDS的设置如下:

IP介绍

如上图所示调用FPGA DDS IP

翻译如下:

1、模式选择--(1)相位和波形数据 (2)相位数据 (3)波形数据

2、系统时钟设置,这里选用系统时钟100MHz,

3、设置通道数;

4、模式选择,两种模式,一般选择standard模式;

5、选择在System Parameters下进行参数设置

6、输出数据宽度和频率精度

偏移宽度计算公式如下:

数据位宽公式如下:

其中SFDR就是上图中的dB参数;

运行设置如下:

1、相位的增量(PINC)和偏移(POFF)

Fixed(固定模式):运行前确定,运行中不可更改,占用资源最少;

Programmable(编程模式): 运行时可修改,DDS频率在不同模式下进行切换;

Streaming(流模式):参数取决于输入的相位值,适用于DDS频率频繁变动的模式;

2、数据输出格式

sine通道输出;

cosine通道输出;

sine和cosine同时输出;

5、相位输出,本次设计对相位无要求,去掉。

其他的默认模式不做处理。

接口格式设置:

例如复位,数据流等控制,如有需求可以修改。

默认输出频率配置:

根据设置的信号,400Hz信号默认输入值为0x20c;

这个值怎么来的呢?

本设计使用的时钟是102.4MHz,根据phase width公式计算出phase width的宽度为27位;

再根据以下公式设置参数:

其中f_clk=102.4MHz,B=27。简单的理解就是2的27次方将102.4MHz做等分处理,计算出来的刻度是102400000/134217728=0.7629Hz。需要输出400Hz,那么设置的值为524,转换成16进制为20c。

啁啾信号是什么

啁啾信号‌是一种信号,其频率随时间变化,这种变化在时域上表现为脉冲性质的表征。啁啾信号分为正啁啾和负啁啾,其中正啁啾是频率随时间增加,而负啁啾则是频率随时间减少。信号如下图所示:

FPGA代码

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/01/10 11:11:34
// Design Name: 
// Module Name: DDS_CTRL_TOP
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module DDS_CTRL_TOP(
	input sys_clk,
	input sys_rst_n,
	
	input s_axis_dds_config_tvalid,
	input[15:0] s_axis_dds_config_tdata,
	//chirp
	input[15:0] chirp_fre_start,
	input[15:0] chirp_fre_stop,
	input[15:0] chirp_fre_step,
	input[15:0] chirp_fre_step_time,
	input chirp_en,
	
	output reg s_axis_config_tvalid,
	output reg[31:0] s_axis_config_tdata
	
    );
	
parameter us_time_num = 'd1024;	//10us
	
reg s_axis_config_chirp_tvalid;
reg[23:0] s_axis_dds_chirp_config_tdata;
reg chirp_mode;0 递增 1 递减 
reg[15:0] us_time_cnt;
reg[15:0] clk_cnt;
reg step_en;
reg us_time_cnt_en;
reg us_time_cnt_en_r1;


always @(posedge sys_clk)begin
	us_time_cnt_en_r1 <= us_time_cnt_en;
end



always @(posedge sys_clk or negedge sys_rst_n)begin
	if(sys_rst_n == 'd0)begin
		chirp_mode <= 'd0;
	end
	else if(chirp_fre_start <= chirp_fre_stop)begin
		chirp_mode <= 'd0;
	end
	else begin
		chirp_mode <= 'd1;
	end
end


always @(posedge sys_clk or negedge sys_rst_n)begin
	if(sys_rst_n == 'd0)begin
		us_time_cnt_en <= 'd0;
	end
	else if(chirp_en == 'd1)begin
		us_time_cnt_en <= 'd1;
	end
	else if(chirp_mode == 'd0 && s_axis_dds_chirp_config_tdata >= chirp_fre_stop && us_time_cnt == chirp_fre_step_time - 'd1 && clk_cnt >= us_time_num - 'd2)begin
		us_time_cnt_en <= 'd0;
	end
	else if(chirp_mode == 'd1 && s_axis_dds_chirp_config_tdata <= chirp_fre_stop && us_time_cnt == chirp_fre_step_time - 'd1 && clk_cnt >= us_time_num - 'd2)begin
		us_time_cnt_en <= 'd0;
	end
end



always @(posedge sys_clk or negedge sys_rst_n)begin
	if(sys_rst_n == 'd0)begin
		us_time_cnt <= 'd0;
		clk_cnt <= 'd0;
		step_en <= 'd0;
	end
	else if(us_time_cnt_en == 'd1 && us_time_cnt == chirp_fre_step_time - 'd1 && clk_cnt >= us_time_num - 'd1)begin
		us_time_cnt <= 'd0;
		step_en <= 'd1;
		clk_cnt <= 'd0;
	end
	else if(us_time_cnt_en == 'd1 && clk_cnt >= us_time_num - 'd1)begin
		us_time_cnt <= us_time_cnt + 'd1;
		clk_cnt <= 'd0;
		step_en <= 'd0;
	end
	else if(us_time_cnt_en == 'd1)begin
		clk_cnt <= clk_cnt + 'd1;
		step_en <= 'd0;		
	end
	else begin
		us_time_cnt <= 'd0;
		clk_cnt <= 'd0;
		step_en <= 'd0;
	end
end


	

always @(posedge sys_clk or negedge sys_rst_n)begin
	if(sys_rst_n == 'd0)begin
		s_axis_config_chirp_tvalid <= 'd0;
		s_axis_dds_chirp_config_tdata <= 'd0;
	end
	else if(chirp_en == 'd1)begin
		s_axis_config_chirp_tvalid <= 'd1;
		s_axis_dds_chirp_config_tdata <= chirp_fre_start;		
	end
	else if(step_en == 'd1 && chirp_mode == 'd0)begin
		s_axis_config_chirp_tvalid <= 'd1;
		s_axis_dds_chirp_config_tdata <= s_axis_dds_chirp_config_tdata + chirp_fre_step;		
	end
	else if(step_en == 'd1 && chirp_mode == 'd1)begin
		s_axis_config_chirp_tvalid <= 'd1;
		s_axis_dds_chirp_config_tdata <= s_axis_dds_chirp_config_tdata - chirp_fre_step;		
	end
	else if(us_time_cnt_en == 'd0 && us_time_cnt_en_r1 == 'd1)beginover 
		s_axis_config_chirp_tvalid <= 'd1;
		s_axis_dds_chirp_config_tdata <= 'd0;		
	end
	else begin
		s_axis_config_chirp_tvalid <= 'd0;
	end
end


	

always @(posedge sys_clk or negedge sys_rst_n)begin
	if(sys_rst_n == 'd0)begin
		s_axis_config_tvalid <= 'd0;
		s_axis_config_tdata <= 'd0;
	end
	
	else if(s_axis_dds_config_tvalid == 'd1)begin
		s_axis_config_tvalid <= 'd1;
		s_axis_config_tdata <= s_axis_dds_config_tdata;
	end
	else begin
		s_axis_config_tvalid <= s_axis_config_chirp_tvalid;
		s_axis_config_tdata <= s_axis_dds_chirp_config_tdata;	
	end
end	
	
	
	
	
	
endmodule

本代码可以实现啁啾信号的起始频率,终止频率,频率步进,频率步进所持续的时间。

FPGA仿真代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2024/08/23 14:44:30
// Design Name: 
// Module Name: DDS_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module DDS_tb(

    );

reg sys_clk;
reg sys_rst_n;	


wire s_axis_config_l_tvalid;
wire[31:0] s_axis_config_l_tdata;
wire s_axis_config_r_tvalid;
wire[31:0] s_axis_config_r_tdata;
wire[15:0] dds_data_l;
wire[15:0] dds_data_r;	
reg chirp_en;

	
always #5 sys_clk = ~sys_clk;	
	
	
initial begin
	sys_clk = 'd0;
	sys_rst_n = 'd0;
	chirp_en = 'd0;
	#30_000
	sys_rst_n = 'd1;
	#30_000
	repeat(1)@(posedge sys_clk);
	chirp_en = 'd1;
	repeat(1)@(posedge sys_clk);
	chirp_en = 'd0;
	
end	
	
	
DDS_CTRL_TOP	DDS_CTRL_TOP_L_inst(

	.sys_clk(sys_clk),
	.sys_rst_n(sys_rst_n),
	
	dds fixed voice
	.s_axis_dds_config_tvalid('d0),
	.s_axis_dds_config_tdata('d0),
	//chirp
	.chirp_fre_start(16'h147a),
	.chirp_fre_stop(16'h051e),
	.chirp_fre_step(16'h0030),
	.chirp_fre_step_time(16'h0004),
	.chirp_en(chirp_en),
	/ out
	.s_axis_config_tvalid(s_axis_config_l_tvalid),
	.s_axis_config_tdata(s_axis_config_l_tdata)


);



DAC_DDS	DAC_DDS_L_INST(
	
	.aclk(sys_clk),
	.s_axis_config_tvalid(s_axis_config_l_tvalid),
	.s_axis_config_tdata(s_axis_config_l_tdata),
	.m_axis_data_tvalid(),
	.m_axis_data_tdata(dds_data_l)

);


	
	
endmodule

仿真波形如下:ru

如上图所示,DDS输出波形逐渐递减的啁啾信号。

如有疑问,欢迎提问。

相关推荐
石牌桥网管36 分钟前
OpenSSL 生成根证书、中间证书和网站证书
网络协议·https·openssl
Qingniu012 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
深圳市青牛科技实业有限公司4 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
DS小龙哥4 小时前
基于Zynq FPGA的雷龙SD NAND存储芯片性能测试
fpga开发·sd nand·雷龙·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
Mr.谢尔比5 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie5 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
阿尔帕兹7 小时前
构建 HTTP 服务端与 Docker 镜像:从开发到测试
网络协议·http·docker
FeelTouch Labs8 小时前
Netty实现WebSocket Server是否开启压缩深度分析
网络·websocket·网络协议
极客小张8 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩