数字信号处理专题——dds函数发生器环路demo(代码片段)

moluoqishi moluoqishi     2022-12-19     710

关键词:

一、前言

  会FPGA硬件描述语言、设计思想和接口协议,掌握些基本的算法是非常重要的,因此开设本专题探讨些基于AD DA数字信号处理系统的一些简单算法,在数字通信 信号分析与检测等领域都会或多或少有应用。我们还是从老生常谈的DDS函数发生器开始,讲解DAC ADC基本使用以及DDS算法原理与设计方式。

二、设计预期

      功能:基于ROM的频率可调DDS正弦函数发生器

  DAC ADC型号与设计参数:DAC为AD9708,更新速率125MSPS,精度8bit;ADC为AD9280,采样率32MSPS,精度8bit。由于ADC采样率限制,设计使用32MHZ频率时钟更新与采样数据,并将ROM深度定义为1024.

  验证手段:MATLAB产生正弦函数,经过8bit量化后存储在ROM中,数据经过DAC 电缆 ADC环回到FPGA,ILA抓取ADC接收数据波形,观察对比发送与接收数据是否相近。

三、DDS原理

  这里只介绍DDS的基本思想,关于详细原理,请参考:【图文】DDS原理_百度文库 https://wenku.baidu.com/view/11cfbf85a0116c175f0e4818.html 

  实际上,DDS的核心就是将正弦或余弦函数存储在ROM中,利用相位累加特性通过采用不同的步长对ROM寻址的方式产生频率可调正弦波。另外需要注意产生信号的频率范围要满足奈奎斯特采样定理,该定理支持若想无失真恢复原始信号,采样频率必须大于等于信号最高频率成分的2倍。反过来说:产生信号的最高频率小于等于最高频率成分的1/2.采样频率即为FPGA是时钟频率。为防止信号混叠,一般取最高频率成分的1/3.

 四、MATLAB产生正弦序列.coe文件及ROM初始化

技术分享图片

技术分享图片

   MATLAB产生频率为1/2*pi标准正弦序列。验证无误后,在VIVADO中调用Block Memory Generator IP核,配置为单口ROM,使用刚才产生的系数文件初始化ROM地址数据。

技术分享图片

五、DAC ADC驱动

  该设计使用的DAC ADC均为为低速并口转换芯片,无需配置,只要FPGA给出时钟信号,并输出/入并行数据即可。根据AD9708 datasheet时序图,其在时钟上升沿采样,故FPGA在输出时钟下降沿更新数据可满足建立与保持时间要求。ADC同样上升沿开始更新数据,接收端在时钟是上升沿采集数据,这样每一时钟周期可以采到上一拍送出的数据。

技术分享图片

六、函数发生器及测试工程设计

技术分享图片
 1 `timescale 1ns / 1ps
 2 
 3 module sin_generator#(parameter FCW_W = 16,
 4                                 DAC_W = 8)
 5  (
 6     input               clk,//DAC采样时钟 由PLL产生
 7     input               rst_n,
 8 
 9     input  [FCW_W-1:0]  fcw,
10     output [DAC_W-1:0]  dac_data,
11     output              dac_clk
12     );
13 
14 reg [ (FCW_W-1):0]  sum     ;
15 wire [9:0] addra;
16 //reg [9:0] addra;//地址测试信号
17 wire ena;
18 wire [7:0] douta;
19 
20   //相位累加器
21   //时钟下降沿产生数据 DAC上升沿采样
22 always @(negedge clk or negedge rst_n )begin 
23     if(rst_n==0) begin
24         sum <= (0)  ;
25     end
26     else begin
27         sum <= (sum+fcw)  ;
28     end 
29 end
30 
31 assign addra = sum[FCW_W-1-:10];
32 
33 //rom地址测试
34 /*always @(posedge clk or negedge rst_n )begin 
35     if(rst_n==0) begin
36         addra <= (0)  ;
37     end
38     else begin
39         addra <= (addra+1)  ;
40     end 
41 end*/
42 
43 
44 blk_mem_gen_0 u_bram (
45   .clka(clk),    // input wire clka
46   .ena(ena),      // input wire ena
47   .addra(addra),  // input wire [9 : 0] addra
48   .douta(douta)  // output wire [7 : 0] douta
49 );
50 assign ena = 1b1;
51 //输出信号
52 assign dac_data = douta;
53 assign dac_clk = ~clk;
54 
55 endmodule
sin_generator

  函数发生器模块由输入端口fcw数值确定频率控制字。测试工程顶层包括差分时钟转单端时钟原语,用于产生DAC ADC时钟的PLL 函数发生器模块,生成特定频率控制字的VIO IP核,还有接收端ADC数据采样逻辑以及ILA 调试IP核。

技术分享图片
 1 `timescale 1ns / 1ps
 2 
 3 
 4 module DDS_Demo_top
 5 #(parameter AD_DA_W = 8)
 6     (
 7     input sys_clk_p,
 8     input sys_clk_n,
 9     input rst_n,
10 
11     output [AD_DA_W-1:0] DAC_data,
12     output DAC_clk,
13 
14     input [AD_DA_W-1:0] ADC_data,
15     output ADC_clk
16     );
17 
18 localparam FCW_W = 16;
19 
20 wire sys_clk_ibufg;
21 wire clk_dac,clk_adc;
22 reg [ (AD_DA_W-1):0]  data_ad     ;
23 
24 wire [FCW_W-1 : 0] probe_out0;
25 wire [AD_DA_W*2-1:0] probe0;
26 
27 //ADC接口信号
28 //ADC在时钟上升沿后送出数据,FPGA下一个上升沿采样
29 assign ADC_clk = clk_adc;
30 
31 always @(posedge clk_adc or negedge rst_n )begin 
32     if(rst_n==0) begin
33         data_ad <= (0)  ;
34     end
35     else begin
36         data_ad <= (ADC_data)  ;
37     end 
38 end
39 
40 
41 /***************************************子模块例化***************************************/
42 IBUFGDS #
43 (
44 .DIFF_TERM ("FALSE"),
45 .IBUF_LOW_PWR ("FALSE")
46 )
47 u_ibufg_sys_clk
48 (
49 .I (sys_clk_p),
50 .IB (sys_clk_n),
51 .O (sys_clk_ibufg)
52 );
53 
54 clk_wiz_0 u_pll
55    (
56     // Clock out ports
57     .clk_out1(clk_dac),         // output clk_out1
58     .clk_out2(clk_adc),         // output clk_out2
59     // Status and control signals
60     .resetn(rst_n),             // input resetn
61     .locked(),                  // output locked
62    // Clock in ports
63     .clk_in1(sys_clk_ibufg));   // input clk_in1
64 
65 sin_generator#(.FCW_W(FCW_W),
66                .DAC_W(AD_DA_W))
67 u_sin_gen
68  (
69     .clk      (clk_dac)  ,//DAC采样时钟 由PLL产生
70     .rst_n    (rst_n)  ,
71     .fcw      (probe_out0)  ,
72     .dac_data (DAC_data)  ,
73     .dac_clk  (DAC_clk)  //由clk_dac产生
74     );
75 
76 //debug cores
77 vio_0 u_vio (
78   .clk(clk_dac),                // input wire clk
79   .probe_out0(probe_out0)  // output wire [15 : 0] probe_out0
80 );
81 
82 ila_0 u_ila (
83     .clk(clk_adc), // input wire clk
84     .probe0(probe0) // input wire [15:0] probe0
85 );
86 
87 assign probe0[7:0] = DAC_data;
88 assign probe0[15:8] = ADC_data;
89 
90 endmodule
DDS_Demo

  最后添加引脚约束文件:

技术分享图片
 1 #################################clock && reset###############################################
 2 create_clock -period 5 [get_ports sys_clk_p]
 3 set_property PACKAGE_PIN R4 [get_ports sys_clk_p]
 4 set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_p]
 5 
 6 set_property PACKAGE_PIN T6 [get_ports rst_n]
 7 set_property IOSTANDARD LVCMOS15 [get_ports rst_n]
 8 
 9 #####################DAC PIN connect J4 expansion interface##########################
10 set_property PACKAGE_PIN H14 [get_ports DAC_clk]
11 set_property IOSTANDARD LVCMOS33 [get_ports DAC_clk]
12 
13 set_property PACKAGE_PIN J14 [get_ports DAC_data[7]]
14 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[7]]
15 set_property PACKAGE_PIN H15 [get_ports DAC_data[6]]
16 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[6]]
17 set_property PACKAGE_PIN J15 [get_ports DAC_data[5]]
18 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[5]]
19 set_property PACKAGE_PIN G13 [get_ports DAC_data[4]]
20 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[4]]
21 set_property PACKAGE_PIN H13 [get_ports DAC_data[3]]
22 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[3]]
23 set_property PACKAGE_PIN J21 [get_ports DAC_data[2]]
24 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[2]]
25 set_property PACKAGE_PIN J20 [get_ports DAC_data[1]]
26 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[1]]
27 set_property PACKAGE_PIN G16 [get_ports DAC_data[0]]
28 set_property IOSTANDARD LVCMOS33 [get_ports DAC_data[0]]
29 
30 #####################ADC PIN connect J4 expansion interface##########################
31 
32 set_property PACKAGE_PIN D22 [get_ports ADC_clk]
33 set_property IOSTANDARD LVCMOS33 [get_ports ADC_clk]
34 
35 set_property PACKAGE_PIN G21 [get_ports ADC_data[7]]
36 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[7]]
37 set_property PACKAGE_PIN G22 [get_ports ADC_data[6]]
38 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[6]]
39 set_property PACKAGE_PIN H20 [get_ports ADC_data[5]]
40 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[5]]
41 set_property PACKAGE_PIN G20 [get_ports ADC_data[4]]
42 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[4]]
43 set_property PACKAGE_PIN J22 [get_ports ADC_data[3]]
44 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[3]]
45 set_property PACKAGE_PIN H22 [get_ports ADC_data[2]]
46 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[2]]
47 set_property PACKAGE_PIN K21 [get_ports ADC_data[1]]
48 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[1]]
49 set_property PACKAGE_PIN K22 [get_ports ADC_data[0]]
50 set_property IOSTANDARD LVCMOS33 [get_ports ADC_data[0]]
clk_pin

七、实验结果分析

  依据之前的参数和DDS信号频率公式,所生成正弦函数频率最好在32/2^16~32/3MHZ之内,使用VIO改变频率控制字数值,观察ILA抓取的发送与接收数据模拟形式波形。任意给出三组频率范围内波形,频率依次由低到高。

技术分享图片

技术分享图片

技术分享图片

  总体来讲还是比较简单。搭建好DAC ADC环路,后面可以验证些滤波 同步算法,或者做些数字频率计、示波器之类的实用设计。

bgd通信15-1150206102王嘉良dds信号发生器

...源所采用的用模拟方式生成信号不同,它是将先进的数字信号处理理论与方法引入信号合成领域。DDS技术在精确度、灵活度等方面都超过模拟信号发生器。并且DDS可实现相位连续变化,且具有良好频谱的信号,这是传统方法无法... 查看详情

采用dds(数字频率合成法)设计信号发生器

DDS主要由相位累加器、波形存储模块和数模转接器等组成。插入一块D/A转换器,然后编制一小段程序,微机输出的数字量经过D/A转换成小阶梯式模拟量波形。在经过低通滤波器滤除引起出1一段时间,再输出0一段时间,反复运行... 查看详情

采用dds(数字频率合成法)设计信号发生器

§2.1设计指导思想用大规模CPLD设计多功能信号发生器,要求能够输出方波、锯齿波、三角波、正弦波。具体是用VHDL硬件描述语言编写多功能信号发生器程序,经过编译、仿真,再下载到CPLD器件上,再经数模转换器输出各类波形... 查看详情

dds设计信号发生器

高一150206101Dds数字信号发生器设计方案 DDS的工作原理框图如下     在微机内,若插入一块D/A转换卡,然后编制一段小程序,如连续进行加一运算到一定值,然后连续进行减一运算回到原值,在反复运行该程... 查看详情

dds数字信号发生器

在微机内,若插入一块D/A转换卡,然后编制一段小程序,如连续进行加一运算到一定值,然后连续进行减一运算回到原值,在反复运行该程序,则微机输出的数字量经过d/a转换为小阶梯式模拟量。  在正弦波中,将其一个... 查看详情

采用dds(数字频率合成法)设计信号发生器

1、 数字频率合成的基本原理在微机内,插入一块D/A转换卡,通过编写程序,如连续进行加1运算到一定值,然后连续进行见1运算回到原值,在反复运算该程序,则微机输出的数字量经D/A转换成小阶梯的高频分量。在经过低通... 查看详情

采用dds设计信号发生器

...直接数字频率合成是一种新型的频率合成技术,它把信号发生器的频率稳定度、准确度提高到与基准频率相同的水平,并且可以在很宽的频率范围内进行精细的频率调节。在现代通信领域中,DDS的应用极其广泛。在微机内,插入... 查看详情

fpga+sin基于dds(直接数字合成)的正弦信号发生器模块fpga实现

1.软件版本quartusii12.12.系统概述    DDS(DirectDigitalfrequencySynthesis)即直接数字频率合成器,是一种新型的频率合成技术,具有较高的频率分辨率,快速的频率切换,稳定性好,可灵活产生多种信号的优点。因此,在现... 查看详情

采用dds设计信号发生器,完成设计方案

基于DDS函数信号发生器设计方案 一、基于DDS信号发生器的系统设计方案的提出 1、采用高性能的DDS单片电路解决方案 随着DDS技术和VLSI的不断发展,DDS式频率合成器单片化在九十年代就已经完成。由于DDS芯片性能日趋... 查看详情

第三次电子测量作业bgd150206306

采用DDS(数字频率合成法)设计信号发生器   信号发生器是一种用于产生多种波形信号的仪器,在电子信息行业的设计、生产过程中有着广泛的应用。直接数字频率合成(DDS)技术是一种采用数字化的方法合成所需频率信... 查看详情

bgd140206221

基于DDS信号发生器设计方案 接数字式频率合成器DDS(DirectDigitalSynthesizer),实际上是一种分频器:通过编程频率控制字来分频系统时钟(SYSTEMCLOCK)以产生所需要的频率。DDS有两个突出的特点,一方面,DDS工作在数字域,一... 查看详情

vivado的ddsip核使用以及混频操作(代码片段)

...上变频。本实验基于Vivado2018.2实现。DDS原理:DDS信号发生器采用直接数字合成,英语名DirectDigitalSynthesis,简称为DDS。把信号的发生器的频率稳定度,准确度提到与基准频率相同的水平,并且可以在 查看详情

模块diy——基于dds直接数字频率合成技术自制的可编程任意波形发生器模块(dds原理寄存器解读原理图设计驱动程序-适用于ad9833/ad9834/ad9838)

【系列专栏】:博主结合工作实践输出的,解决实际问题的专栏,朋友们看过来!《QT开发实战》《嵌入式通用开发实战》《从0到1学习嵌入式Linux开发》 查看详情

帮帮我要详细

...于是我把所有的全部卸载后再安装遇到以上问题。在信号发生器的设计中,传统的用分立元件或通用数字电路元件设计电子线路的方法设计周期长,花费大,可移植性差。本设计是利用EDA技术设计的电路,该信号发生器输出信号的频... 查看详情

fpga教程案例68硬件开发板调试8——通过ila在线调试dds信号发生器

FPGA教程目录MATLAB教程目录--------------------------------------------------------------------------------------------------------------------------------目录1.软件版本2.项目工程准备2.1更新芯片型号 查看详情

fpga学习之直接数字频率合成器(dds)(代码片段)

目录FPGA学习之直接数字频率合成器(DDS)FPGA学习之直接数字频率合成器(DDS)DDS的原理:直接数字频率合成器(DirectDigitalSynthesizer,DDS)是一种把数字信号通过D/A转换成模拟信号的数字合成技术。它有... 查看详情

fpga学习之直接数字频率合成器(dds)(代码片段)

目录FPGA学习之直接数字频率合成器(DDS)FPGA学习之直接数字频率合成器(DDS)DDS的原理:直接数字频率合成器(DirectDigitalSynthesizer,DDS)是一种把数字信号通过D/A转换成模拟信号的数字合成技术。它有... 查看详情

求一篇关于信号发生器的英文文章

求一篇关于信号发生器的英文文章,最好是基于DDS之类的,相关就可以,找了好久都找不到一篇英文文章,要毕业了,还要一篇英文翻译,有没谁有关于这方面的英文文章,期刊什么的都可以,大概有45页左右就可以了多了我也... 查看详情