一、设计目标

根据DDS技术原理,在vavido上编写DDS信号源硬件逻辑语言,实现频率、幅度、波形可调的信号源发生器。

频率调节分为11个档位,分别是:1Hz、10Hz、100Hz、500Hz、1kHz、5kHz、10kHz、50kHz、100kHz、200kHz、500kHz;

波形调节有四种波形:正弦波、三角波、锯齿波、方波;

幅度调节有五种档位:分别是1倍、1/2倍、1/4倍、1/8倍、1/16倍;

以上设计指标在遇到实际需求时,都可以根据设计在响应的添加或者减少。

二、设计软件及工具

Vivado 2019.01

Vivado包含的功能:编辑器、RTL分析、仿真、综合、生成比特流等。

使用FPGA开发板,芯片为xc7a35系列芯片。此开发板的外设包含:矩阵键盘、开关、串口、VGA、BRAM、LED、七段数码管、蜂鸣器。

由于没有示波器,所以本次采用vavido中的仿真来验证实验结果,也没有采用开发板,本次设计所需要的输入也没有与按键相联系,如果后续有需求的话,可以添加进去。

三、设计思路

本次设计采用DDS技术来实现函数信号源的功能,采用FPGA来作为控制模块,其中分别设立了频率设置模块、幅度设置模块、DDS模块(包含波形设置模块)、主模块这四个部分,以下框图便是设计思路图。

四、设计原理

DDS全称为直接数字频率合成(Direct Digital Synthesis),其基本原理是在一个周期波形数据下,通过选取其中全部数据或抽样部分数据组成新的波形,由奈奎斯特采样定理可知,最低两个采样点就可以组成一个波形,但实际上最少需要4个点。其原理框图如下:

DDS 以数控振荡器的方式,产生频率、相位可控制的波形,需要基准时钟源、相位累加器、相位调制器、正弦ROM 查找表等

频率控制字B 和相位控制字N分别控制DDS 所输出的波形的频率和相位。

DDS系统的核心是相位累加器,它由一个N位累加器与N 位相位寄存器构成。时钟脉冲每触发一次,累加器便将频率控制数据与相位寄存器输出的累加相位数据相加,然后把相加后的结果送至相位寄存器的数据输入端。相位寄存器将累加器在上一个时钟作用后所产生的新相位数据反馈到累加器的输入端,以使加法器在下一个时钟的作用下继续与频率控制数据相加。这样,相位累加器在参考时钟的作用下将进行线性相位累加,当相位累加器累加满时,就会产生一次溢出, 以完成一个周期性的动作,这个周期就是DDS合成信号的一个频率周期,相位累加器的溢出频率就是DDS 输出的信号频率。相位寄存器的输出与相位控制字相加, 结果作为波形查找表的地址。

查找表由ROM 构成,其内部存有一个完整周期波形的数字幅度信息, 每个查找表的地址对应正弦波中的一个相位点。查找表把输入地址信息映射成正弦波幅度信号, 同时输出到D/A 转换器的输入端, 通过D/A 可将数字量形式的波形幅值转换成所要求的合成频率模拟量形式信号。

五、DDS中查找表(生成三角波、正弦波、锯齿波、方波)的matlab代码 

正弦波代码:
%% sin-cos wave data write in coe file
clear all ;
clc ;
N = 4096 ;
y = zeros(N , 1) ;
for i = 1:1:N x = i ;%y(i,1) = ceil( 2047*sin(x*2*pi/N) ) + 2047 ;y(i,1) = ceil( 2047*cos(x*2*pi/N) ) + 2047;
end
plot(y);
hold on;
fid = fopen('D:\Vavido\DDS\cos_4096.coe','wt');
%- standard format
fprintf( fid, 'MEMORY_INITIALIZATION_RADIX = 10;\n');
fprintf( fid, 'MEMORY_INITIALIZATION_VECTOR =\n');
%- write data in coe file
for i = 1:1:Nfprintf(fid,'%d,\n',y(i,1));
end
fclose(fid);三角波代码:
%% sanjiao wave data write in coe file
clear all ;
clc ;
N = 4096 ;
y = zeros(N , 1) ;
for i = 1:1:N if(i <2049)y(i,1) = 2*(i-1)+1;elsey(i,1) = -2*(i-2049)+4095;end
end
plot(y);
hold on;
fid = fopen('D:\Vavido\DDS\sanjiao_4096.coe','wt');
%- standard format
fprintf( fid, 'MEMORY_INITIALIZATION_RADIX = 10;\n');
fprintf( fid, 'MEMORY_INITIALIZATION_VECTOR =\n');
%- write data in coe file
for i = 1:1:Nfprintf(fid,'%d,\n',y(i,1));
end
fclose(fid);方波:
%% fang wave data write in coe file
clear all ;
clc ;
N = 4096 ;
y = zeros(N , 1) ;
for i = 1:1:N if(i < 2049)y(i,1) = 4095 ;elsey(i,1) = 0 ;end
end
plot(y);
hold on;
fid = fopen('D:\Vavido\DDS\fangbo_4096.coe','wt');
%- standard format
fprintf( fid, 'MEMORY_INITIALIZATION_RADIX = 10;\n');
fprintf( fid, 'MEMORY_INITIALIZATION_VECTOR =\n');
%- write data in coe file
for i = 1:1:Nfprintf(fid,'%d,\n',y(i,1));
end
fclose(fid);锯齿波:
% 锯齿波 wave data write in coe file
clear all;
clc;
N = 4096;
y = zeros(N , 1);
F=2047;for i = 1:1:N y(i,1) =fix(F*sawtooth(i*2*pi/4096)+F);  end
plot(y);
hold on;
fid = fopen('D:\Vavido\DDS\juchi_4096.coe','wt');
%- standard format
fprintf( fid, 'MEMORY_INITIALIZATION_RADIX = 10;\n');
fprintf( fid, 'MEMORY_INITIALIZATION_VECTOR =\n');
%- write data in coe file
for i = 1:1:Nfprintf(fid,'%d,\n',y(i,1));
end
fclose(fid);

注意!!! 记得修改生成的.coe文件的路径,然后在vavido中配置的时候一定要主要深度和跨度,是多少就要配置多少!

六、代码如下

TOP模块:

module TOP(
input clk,
input rst_n,
input [1:0] wave,
input [11:0]  p_word,
input [2:0]  AM,
input [3:0]    f_set,
output [11:0] dac_dataa
);
wire [31:0] f_word;
wire [4:0] amplitude;
DDS uut1(
.clk(clk),
.rst_n(rst_n),
.wave(wave),
.f_word(f_word),
.p_word(p_word),
.amplitude(amplitude),
.dac_dataa(dac_dataa)
);
F_word_set uut2(
.clk(clk),
.rst_n(rst_n),
.f_set(f_set),
.f_word(f_word)
);
A_set uut3(
.clk(clk),
.rst_n(rst_n),
.AM(AM),
.amplitude(amplitude)
);
endmodule

DDS模块:

module DDS(
input clk,                           //输入参考时钟
input rst_n,                         //复位按键
input [1:0] wave,                    //输入控制波形
input [31:0]  f_word,                //输入频率控制字控制频率
input [11:0]  p_word,                //输入相位控制字控制相位
input [4:0]   amplitude,             //输入控制幅度
output [11:0] dac_dataa       //从dac中输出的数值
);
wire [11:0] dac_data0;   //从rom0中输出的数据
wire [11:0] dac_data1;   //从rom2中输出的数据
wire [11:0] dac_data2;   //从rom2中输出的数据
wire [11:0] dac_data3;   //从rom3中输出的数据reg [11:0] dac_data;
assign dac_dataa=dac_data;//波形选择always @ (posedge clk or negedge rst_n)beginif(!rst_n) begindac_data <= 11'd0;  endelsebegincase(wave)2'b00:dac_data<=dac_data0/amplitude;   //显示正弦波2'b01:dac_data<=dac_data1/amplitude;   //显示三角波2'b10:dac_data<=dac_data2/amplitude;   //显示锯齿波2'b11:dac_data<=dac_data3/amplitude;   //显示方波default:;endcaseendend//相位累加器reg [31:0]  fre_acc;always @ (posedge clk or negedge rst_n)beginif(!rst_n)beginfre_acc<=0;endelsebeginfre_acc<=fre_acc+f_word;end  end//两个控制字的同步寄存器  reg [31:0] f_word_reg;reg [11:0] p_word_reg;always @ (posedge clk or negedge rst_n)beginif(!rst_n)beginf_word_reg<=0;endelsebeginf_word_reg<=f_word;endendalways @ (posedge clk or negedge rst_n)beginif(!rst_n)beginp_word_reg<=0;endelsebeginp_word_reg<=p_word;endend//生成查找表地址  wire [11:0] addr;//这个是连接线assign addr = fre_acc[31:20]+p_word_reg;blk_mem_gen_0 zhengxian_wave(.clka(clk),.addra(addr),.douta(dac_data0));//三角波blk_mem_gen_1 sanjiao_wave(.clka(clk),.addra(addr),.douta(dac_data1));//锯齿波blk_mem_gen_2 juchi_wave(.clka(clk),.addra(addr),.douta(dac_data2));//方波blk_mem_gen_3 fang_wave(.clka(clk),.addra(addr),.douta(dac_data3));
endmodule

F_word_set模块:频率设定模块

module F_word_set(
input clk,
input rst_n,
input [3:0] f_set,
output  reg [31:0]  f_word);//由f_set决定频率的大小always @ (posedge clk or negedge rst_n)  //x=(2^32)*20/T=(2^32)*20*f(hz)/1000000000beginif(!rst_n)beginf_word<=0;endelsebegincase(f_set)4'd0:f_word<=32'd86; //1hz4'd1:f_word<=32'd859; //10hz4'd2:f_word<=32'd8590; //100hz4'd3:f_word<=32'd42950; //500hz4'd4:f_word<=32'd85899; //1khz4'd5:f_word<=32'd429497; //5khz4'd6:f_word<=32'd858993; //10khz4'd7:f_word<=32'd4294967; //50khz4'd8:f_word<=32'd8589935; //100khz4'd9:f_word<=32'd17179869; //200khz4'd10:f_word<=32'd42949673; //500khzdefault:;endcaseendend
endmodule

A_set模块:幅度调节模块

module A_set(
input clk,
input rst_n,
input [2:0] AM,
output reg [4:0] amplitude
);
always @ (posedge clk or negedge rst_n)
beginif(!rst_n) beginamplitude<=0;end     elsebegincase(AM)3'd0:amplitude<=5'd1;3'd1:amplitude<=5'd2;3'd2:amplitude<=5'd4;3'd3:amplitude<=5'd8;3'd4:amplitude<=5'd16;default:amplitude<=5'd1;    endcaseend
end
endmodule

仿真模块:

module DDS_sm();
reg clk;
reg rst_n;
reg [1:0] wave;
reg [11:0] p_word;
reg [2:0] AM;
reg [3:0] f_set;
wire [11:0] dac_dataa;
TOP uut(
.clk(clk),
.rst_n(rst_n),
.wave(wave),
.p_word(p_word),
.AM(AM),
.f_set(f_set),
.dac_dataa(dac_dataa)
);
initial begin
clk<=1'b0;
wave<=2'b00;
p_word<=12'd0;
AM<=3'b000;
f_set<=4'd5;
rst_n<=1'b0;
#5 rst_n<=1'b1;
end
always #10 clk=~clk;
endmodule

七、仿真结果 

1、正弦波

2、三角波

3、锯齿波

4、方波

八、总结

第一次写csdn,还有些不熟练,大家有不清楚的地方可以在评论区滴滴我,也可以私聊我;不对的地方还请大家指正!谢谢大家.

基于FPGA的DDS信号发生器(vivado版本)相关推荐

  1. 基于FPGA的DDS信号发生器

    基于FPGA的DDS信号发生器     两个礼拜前就像写这个文档了,但是一直鸽到现在,主要是人摆了.还有个技术上的原因是,我想用串口屏显示波形,在串口调试助手上返回的数据是对的,但是发到串口屏上啥反应 ...

  2. 【FPGA实例】基于FPGA的DDS信号发生器设计

    原文链接来源:www.runoob.com 基于FPGA的DDS信号发生器设计 DDS 原理 ------DDS(直接频率合成) 技术是根据奈奎斯特抽样定理及数字处理技术,把一系列的模拟信号进行不失真 ...

  3. CASE_05 基于FPGA的DDS信号发生器

             该系类博客序言和资源简介可浏览该博客:PREFACE FPGA经典案例序言 快速了解该系列博客的内容与可用 资源. 目录 1 简介 2 DDS原理与方案 2.1 方案一:基于CORD ...

  4. 基于FPGA的DDS在Vivado中仿真以及在ZYNQ7020上板的实现(1)

    本系列文章详细介绍了DDS在Vivado中的仿真实现.综合.布线.生成bit流以及上板的过程. (一)初始配置 1)先下载Vivado软件,本人使用的是2019.1版本的Vivado,使用其他版本Vi ...

  5. 基于FPGA的DDS在Vivado中仿真以及在ZYNQ7020上板的实现(2)

    接上一节,从仿真文件的编写开始 (三)仿真文件testbench 1)首先先点击add source 2)建立 simulation source文件 3)点击create file 4)给文件命名 ...

  6. 基于FPGA的DDS 信号发生器(一)

    用DDS求角度的正弦值 1 DDS原理 1.1 书上的解释 1.2 自己的理解 2 DDS IP的参数设置 3 Vivado实现 3.1 编写源文件 3.2 编写testbench文件 3.3 仿真结 ...

  7. 基于FPGA的DDS 信号发生器(三)

    控制正弦波的频率和相位(频率控制字+相位控制字) 1 DDS原理 1.1 书上的解释 1.2 自己的理解 2 DDS IP的参数设置 3 源码 3.1 顶层文件 3.2 频率控制字模块 3.3 相位控 ...

  8. 国产紫光FPGA实现DDS信号发生器

    前言 随着信息技术的迅速发展,FPGA作为半定制电路具有可重复编程.计算能力强等优势,进入人们的视野,并在未来将发挥出越来越重要的作用. 作为电子专业的大三学生,我们小组在老师的带领下对现有国产FPG ...

  9. 基于FPGA实现DDS正弦波发生器

    名言:学无止境. 1 开发环境 操作系统:win7 开发软件:ISE14.7 硬件平台:Xilinx FPGA Spartan6 2 DDS简介 DDS(Direct Digital Synthesi ...

最新文章

  1. python版本越高越好吗-5个Python特性 越早知道越好的
  2. python下载word文件-python-docx操作word文件(
  3. ps拖拽组的时候,不卡 - 软件设置篇
  4. python爬虫requests简单案例_python网络爬虫(三)requests库的13个控制访问参数及简单案例...
  5. 理解OAuth 2.0[摘]
  6. java船_Java-货船
  7. 计算机术语仿真,计算机仿真-精.ppt
  8. SpringBoot集成JApiDocs实现自动生成接口文档
  9. python实现规则引擎_几种开源规则引擎(BRE)的比较 转
  10. Android破解过程-滚动的天空
  11. 后量子密码(PQC)决赛入围算法和候选算法
  12. CAD中怎么画指北针?CAD画指北针教程
  13. 通过JDBC-ODBC连接SQL Server数据库
  14. VS2015 编译开源的基于Opencascade的3D查看器Mayo
  15. 关于单页应用(SPA)的经验之谈
  16. QQ防红跳转PHP代码,最新版防红代码!完虐市场上所有防红!!仅需一段代码在QQ打开任意网址即可跳转...
  17. 美军派网络部队前往韩国 防“萨德”泄密
  18. html 图像旋转180度
  19. 相比4G,5G有那些优势满足工业4.0的技术需求
  20. 为什么所谓的“自律”一定要跟坚持挂钩呢?懂一点“行为设计学”,升级对“意义”的认知

热门文章

  1. 去虚拟化 VMware Workstation Pro去虚拟化底层文件修改器
  2. 速算24点java_24点速算游戏 Java 代码
  3. 围棋GUI界面Sabaki的安装与使用
  4. 腾讯云域名与个人树莓派设备的动态域名解析
  5. 单元测试总结反思_英语单元测试教学反思范文
  6. 与门非门在电子计算机中的应用,【E电路】数字电路基础:与门电路
  7. 上海python招聘微信群_Python之微信-微信群发
  8. 自动曝光修复算法附完整C代码
  9. 华中师范大学计算机科学与技术考研辅导,考研求助,华中师范大学的计算机怎么样...
  10. 一般java面试考什么_JAVA面试的时候一般考什么?