基于DDS的数字相移信号发生器.docx
《基于DDS的数字相移信号发生器.docx》由会员分享,可在线阅读,更多相关《基于DDS的数字相移信号发生器.docx(18页珍藏版)》请在冰豆网上搜索。
基于DDS的数字相移信号发生器
EDA课程设计说明书
课程名称__现代电子系统课程设计__
题目_DDS数字移相信号发生器设计__
1.课程设计目的
掌握数字移相信号发生器的工作原理和设计方法;
掌握DDS技术的工作原理;
掌握GW48_SOPC实验箱的使用方法;
了解基于FPGA的电子系统的设计方法。
2.课程设计内容
完成10位输出数据宽度的移相信号发生器的设计,要求使用锁相环,设计正弦波形数据MIF文件,给出仿真波形,增加幅度控制电路,最后进行硬件测试。
3.程序结构剖析
利用FPGA芯片及D/A转换器,采用直接数字频率合成技术,设计实现了一个频率、相位可控的正弦信号发生器,同时阐述了直接数字频率合成(DDS)技术的工作原理、电路结构,及设计的思想和实现方法。
经过设计和电路测试,输出波形达到了技术要求,控制灵活、性能较好,也证明了基于FPGA的DDS设计的可靠性和可行性。
直接数字频率合成(DDS)技术采用数字合成的方法,所产生的信号具有频率分辨率高、频率切换速度快、频率切换时相位连续、输出相位噪声低和可以产生任意波形等诸多优点。
在理论上对DDS的原理及其输出信号的性能进行了分析,完成了基于DDS的数字移相信号发生器的设计,采用VHDL语言,成功地编写出了设计程序,并且在Quartus2软件环境中,对编写的VHDL程序进行了仿真,得到了很好的效果。
在本文中,我们设计了一个频率相移测量仪。
主要分为如下几个部分:
波形数据ROM模块
32位加法器模块
10位加法器模块
32位锁存器模块
10位锁存器模块
4.系统原理及结构
超高速A/D、D/A板GW_ADDA说明
GW_ADDA板含两片10位超高速DAC(转换速率最高150MHz)和一片8位ADC(转换速率最高50MHz),另2片3dB带宽大于260MHz的高速运放组成变换电路。
GW_ADDA板上所有的A/D和D/A全部处于使能状态,除了数据线外,任一器件的控制信号线只有时钟线,这有利于高速控制和直接利用MATLAB/DSPBuilder工具的设计。
GW_ADDA板上工作时钟必须由FPGA的I/O口提供,且DAC和ADC的工作时钟是分开的。
无法直接利用MATLAB和DSPBuilder进行自动流程的设计,优点是时钟频率容易变化,且可通过Cyclone中的PLL的到几乎任何时钟频率。
由此即可测试ADC和DAC的最高转换频率。
两个电位器可分别调协两个D/A输出的幅度(输出幅度峰峰值不可大于5V,否则波形失真);模拟信号从接插口的2针“AIN”输入,J1和J2分别是模拟信号输出的PA、PB口,也可在两挂钩处输出,分别是两个10位DA5651输出口。
注意,使用A/D,D/A板必须打开GW48-PK2主系统板上的+/-12V电源,用后关闭!
附图SOPCGWAC6/12板AD_DA板接口原理图
FPGA是除CPLD外的另一大类大规模可编程逻辑器件,FPGA采用了另
一种可编程逻辑的形成方法,即可编成的查表结构,就是SRAM(静态随机存
储)来构成逻辑函数发生器。
一个N输入查找表(LUT)可以实现N个输入变
量的任何逻辑功能。
图:
FPGA查找表单元
图:
FPGA查表单元内部结构
VHDL是大多数EDA工具都采用的硬件描述语言。
其主要优点有:
功能强大,描述能力强;可移植性好;研制周期短,成本低;可延长设计的生
命周期;具有向ASIC移植的能力。
Quartus2提供了完整的多台设计环境,能够满足各种特定的设计要求。
Quartus2与Matlab和DSPBuilder结合,可以基于FPGA的DSP开发,是DSP
硬件系统实现的关键EDA工具。
同时,Quartus2具备仿真功能,也支持第三方的仿真工具。
5.DDS技术与原理
A.DDS基本原理
B.累加器
C.波形ROM示意图如图
D.系统结构
图:
基于DDS的数字相移信号发生器电路模型图
E.系统功能分析
F.系统结构模块
6.程序代码
主程序
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGiC_UNSIGNED.ALL;
ENTITYDDS_Signal_zhangjiating_jinxinIS
PORT(CLK:
INSTD_LOGIC;--系统时钟
DCLK:
outSTD_LOGIC;
FWORD:
INSTD_LOGIC_VECTOR(7DOWNTO0);--频率控制字
PWORD:
INSTD_LOGIC_VECTOR(7DOWNTO0);--相位控制字
FOUT:
OUTSTD_LOGIC_VECTOR(9DOWNTO0);--可移相正弦信号输出
POUT:
OUTSTD_LOGIC_VECTOR(9DOWNTO0));--参考信号输出
ENDDDS_Signal_zhangjiating_jinxin;
ARCHITECTUREoneOFDDS_Signal_zhangjiating_jinxinIS
COMPONENTdff32--32位锁存器
PORT(LOAD:
INSTD_LOGIC;
DIN:
INSTD_LOGIC_VECTOR(31DOWNTO0);
DOUT:
OUTSTD_LOGIC_VECTOR(31DOWNTO0));
ENDCOMPONENT;
COMPONENTdff10--10位锁存器
PORT(LOAD:
INSTD_LOGIC;
DIN:
INSTD_LOGIC_VECTOR(9DOWNTO0);
DOUT:
OUTSTD_LOGIC_VECTOR(9DOWNTO0));
ENDCOMPONENT;
COMPONENTADDER32--32位加法器
PORT(A:
INSTD_LOGIC_VECTOR(31DOWNTO0);
B:
INSTD_LOGIC_VECTOR(31DOWNTO0);
S:
OUTSTD_LOGIC_VECTOR(31DOWNTO0));
ENDCOMPONENT;
COMPONENTADDER10--10位加法器的设计
PORT(A:
INSTD_LOGIC_VECTOR(9DOWNTO0);
B:
INSTD_LOGIC_VECTOR(9DOWNTO0);
S:
OUTSTD_LOGIC_VECTOR(9DOWNTO0));
ENDCOMPONENT;
COMPONENTSIN_ROM--10位地址10位数据正弦信号数据ROM
PORT(address:
INSTD_LOGIC_VECTOR(9DOWNTO0);
inclock:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(9DOWNTO0));
ENDCOMPONENT;
SIGNALF32B,D32B,DIN32B:
STD_LOGIC_VECTOR(31DOWNTO0);
SIGNALP10B,LIN10B,SIN10B:
STD_LOGIC_VECTOR(9DOWNTO0);
BEGIN
DCLK<=CLK;
F32B(27DOWNTO20)<=FWORD;
F32B(31DOWNTO28)<="0000";
F32B(19DOWNTO0)<="00000000000000000000";
P10B(9DOWNTO2)<=PWORD;
P10B(1DOWNTO0)<="00";
u1:
ADDER32PORTMAP(A=>F32B,B=>D32B,S=>DIN32B);
u2:
dff32PORTMAP(DOUT=>D32B,DIN=>DIN32B,LOAD=>CLK);
u3:
SIN_ROMPORTMAP(address=>SIN10B,q=>FOUT,inclock=>CLK);
u4:
ADDER10PORTMAP(A=>P10B,B=>D32B(31DOWNTO22),S=>LIN10B);
u5:
dff10PORTMAP(DOUT=>SIN10B,DIN=>LIN10B,LOAD=>CLK);
u6:
SIN_ROMPORTMAP(address=>D32B(31DOWNTO22),q=>POUT,inclock=>CLK);
ENDone;
Adder32加法器代码
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYadder32IS
PORT(A:
INSTD_LOGIC_VECTOR(31DOWNTO0);
B:
INSTD_LOGIC_VECTOR(31DOWNTO0);
S:
OUTSTD_LOGIC_VECTOR(31DOWNTO0));
ENDadder32;
ARCHITECTUREbehavOFadder32IS
BEGIN
S<=A+B;
ENDbehav;
Adder10加法器代码
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYadder10IS
PORT(A:
INSTD_LOGIC_VECTOR(9DOWNTO0);
B:
INSTD_LOGIC_VECTOR(9DOWNTO0);
S:
OUTSTD_LOGIC_VECTOR(9DOWNTO0));
ENDadder10;
ARCHITECTUREbehavOFadder10IS
BEGIN
S<=A+B;
ENDbehav;
Dff32锁存器
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYdff32IS
PORT(Load:
INSTD_LOGIC;
DIN:
INSTD_LOGIC_VECTOR(31DOWNTO0);
DOUT:
OUTSTD_LOGIC_VECTOR(31DOWNTO0));
ENDdff32;
ARCHITECTUREbehavOFdff32IS
BEGIN
PROCESS(Load,DIN)
BEGIN
IFLoad'EVENTANDLoad='1'THEN--时钟到来时,锁存输入数据
DOUT<=DIN;
ENDIF;
ENDPROCESS;
ENDbehav;
Dff10锁存器
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYdff10IS
PORT(Load:
INSTD_LOGIC;
DIN:
INSTD_LOGIC_VECTOR(9DOWNTO0);
DOUT:
OUTSTD_LOGIC_VECTOR(9DOWNTO0));
ENDdff10;
ARCHITECTUREbehavOFdff10IS
BEGIN
PROCESS(Load,DIN)
BEGIN
IFLoad'EVENTANDLoad='1'THEN--时钟到来时,锁存输入数据
DOUT<=DIN;
ENDIF;
ENDPROCESS;
ENDbehav;
sin_rom波形数据rom模块
LIBRARYieee;
USEieee.std_logic_1164.all;
LIBRARYaltera_mf;
USEaltera_mf.all;
ENTITYsin_romIS
PORT
(
address:
INSTD_LOGIC_VECTOR(9DOWNTO0);
inclock:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(9DOWNTO0)
);
ENDsin_rom;
ARCHITECTURESYNOFsin_romIS
SIGNALsub_wire0:
STD_LOGIC_VECTOR(9DOWNTO0);
COMPONENTaltsyncram
GENERIC(
address_aclr_a:
STRING;
init_file:
STRING;
intended_device_family:
STRING;
lpm_hint:
STRING;
lpm_type:
STRING;
numwords_a:
NATURAL;
operation_mode:
STRING;
outdata_aclr_a:
STRING;
outdata_reg_a:
STRING;
widthad_a:
NATURAL;
width_a:
NATURAL;
width_byteena_a:
NATURAL
);
PORT(
clock0:
INSTD_LOGIC;
address_a:
INSTD_LOGIC_VECTOR(9DOWNTO0);
q_a:
OUTSTD_LOGIC_VECTOR(9DOWNTO0)
);
ENDCOMPONENT;
BEGIN
q<=sub_wire0(9DOWNTO0);
altsyncram_component:
altsyncram
GENERICMAP(
address_aclr_a=>"NONE",
init_file=>"LUT10X10.mif",
intended_device_family=>"Cyclone",
lpm_hint=>"ENABLE_RUNTIME_MOD=NO",
lpm_type=>"altsyncram",
numwords_a=>1024,
operation_mode=>"ROM",
outdata_aclr_a=>"NONE",
outdata_reg_a=>"UNREGISTERED",
widthad_a=>10,
width_a=>10,
width_byteena_a=>1
)
PORTMAP(
clock0=>inclock,
address_a=>address,
q_a=>sub_wire0
);
ENDSYN;
7.仿真图形
引脚图
硬件下载成功图
8.心得体会
本次基于DDS的数字相移信号发生器,其主要功能在于相位差的实现,并在此基础上完成指定信号的合成输出。
本设计未采用专用DDS芯片,而是通过VHDL语言编程来实现移相信号发生器的主要功能。
整个实验是基于简单正弦信号发生器改进而成,包括好几个子程序。
通过这次的实验过程,我对VHDL技术中的一些结构、要素以及基本语句有了更深的了解与体会。
本实验主要涉及到了例化语句,通过例化语句将五个子程序连接到主程序中。
在程序调试中也出现了很多问题,一些语言上的错误需要注意。
调试过程中,主程序中的例化语句就出现了一些问题,MAP中写前面的应为元件端口名。
这是在后来检查过程中才发现的。
还有一个问题就是输入法的问题,全程应该是在英文输入法下输入的,在输入的过程中我们也出现了一点错误,就是在不知不觉中有几个标点符号是在中文输入法下输入的,因此程序也无法正常运行。
之后是仿真阶段,仿真阶段我们组倒是没有出现问题。
在编程下载过程中也是正常的,直到最后的示波器显示,我们发现示波器上迟迟没有出现信号,检查了好多遍都未能发现问题,只好求助同学。
原来是因为时钟的问题,A/D转换器上未接收到时钟信号,再定义一个时钟,将A/D转换器上的时钟信号与整个模块同步。
整个实验还考察我们的细心程度,一个小小的标点符号错误都将使整个程序无法运行。
还有团队合作的重要性,当局者迷,当你深陷一个一个地方想不到解决的办法时可以求助于同学,站在他的角度或许能比你更直观得发现错误。
只有在理论知识扎实的掌握之后,自己才会在实践中得到应有的发挥,及在工作中的应用,我们要走的路还很遥远。