任意信号发生器设计DDS.docx
《任意信号发生器设计DDS.docx》由会员分享,可在线阅读,更多相关《任意信号发生器设计DDS.docx(18页珍藏版)》请在冰点文库上搜索。
任意信号发生器设计DDS
任意信号发生器设计
发布时间:
2011-07-0812:
45:
53
技术类别:
CPLD/FPGA
修改 | 删除 | 置顶
目 录
绪 论
第1章 DDS原理
1.1DDS原理和结构
1.2DDS的特点
第2章系统总体设计
2.1 设计思路
2.2 系统设计
2.2.2 各底层文件管脚图
第3章程序设计与分析
3.1 程序设计概要
3.2 核心程序分析
3.2.1 数控分频器
3.2.2 多路选择器
3.2.3 三角波生成器
3.2.4 可调节占空比的方波
3.2.5振幅键控(ASK-AmplitudeShiftKeying)
3.2.6移频键控(FSK-FrequencyShiftKeying)
3.2.7移相键控(PSK-PhaseShiftKeying)
3.2.8任意波的产生
3.2.9正弦信号的产生
第4章仿真与测试
4.1QUARTUSII简介
4.2 各模块时序仿真结果
4.2.1 数控分频模块
4.2.2 波形发生模块
4.2.3 多路选择器模块
4.3 硬件测试
结束语
参考文献
谢 辞
绪 论
EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言HDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。
硬件描述语言HDL是EDA技术的重要组成部分,常见的HDL主要有VHDL、Verilog HDL、ABEL、AHDL、System Verilog和SystemC。
其中VHDL、Verilog HDL在现在的EDA设计中使用最多,并且我们学习的是VHDL的编程方法和实用技术。
VHDL的英文全名是VHSIC(VeryHighSpeedIntegratedCircuit)HardwareDescriptionLanguage,由IEEE(TheInstituteofElectricalandElectronicsEngineers)进一步发展,并在1987年作为“IEEE标准1076”公布。
从此VHDL成为硬件描述语言的业界标准之一。
EDA技术的出现,极大地提高了电路设计的效率和可操作性,减轻了设计者的劳动强度。
利用EDA工具,电子设计师可以从概念、算法、协议等开始设计电子系统,大量工作可以通过计算机完成,并可以将电子产品从电路设计、性能分析到设计出IC版图或PCB版图的整个过程的计算机上自动处理完成。
现在对EDA的概念或范畴用得很宽。
包括在机械、电子、通信、航空航天、化工、矿产、生物、医学、军事等各个领域,都有EDA的应用。
目前EDA技术已在各大公司、企事业单位和科研教学部门广泛使用。
例如在飞机制造过程中,从设计、性能测试及特性分析直到飞行模拟,都可能涉及到EDA技术。
本文主要介绍了EDA在设计波形发生器中的应用,完成了锯齿波、三角波、占空比可调的方波、占空比50%的方波以及正弦波设计,同时还能起到对频率、幅值、占空比的调节,用原理图及VHDL语言完成了整个系统的设计,并用实验箱完成了所有功能硬件调试。
第1章 DDS原理
1.1 DDS原理和结构
基于DDS技术的函数信号发生器由相位累加器、波形存储器ROM、数模转换器DAC和低通滤波器LPF组成,相位累加器和波形存储器ROM在FPGA器件EP1K30TC144-3中实现,系统框图如图1所示:
图1DDS系统框图
在系统时钟脉冲fc的作用下,相位累加器以步长K不停地累加(K又称为频率控制字),累加输出作为ROM地址输入进行查表,ROM输出值即是波形数字幅度值,把该数据送至DAC转换成模拟量输出,再经滤波器平滑后输出所需波形。
由相位累加器字长N的限制,累加到一定值后输出将会溢出,这样波形存储器的地址就会循环一次,即输出波形循环一周。
因此改变步长就可以改变相位累加器的溢出时间,在时钟不变的条件下就可改变输出频率。
输出波形的频率为
(1)
由式
(1),合成信号最低频率
,最高频率
,当相位累加器位宽N和基准时钟频率
达到一定要求时,输出频率范围可以很宽,输出分辨率可以很小,趋近于0,这是传统信号发生器无法达到的。
1.2 DDS的特点
优点:
(1)输出频率相对带宽较宽输出频率带宽为50%fs(理论值)。
但考虑到低通滤波器的特性和设计难度以及对输出信号杂散的抑制,实际的输出频率带宽仍能达到40%fs。
(2)频率转换时间短DDS是一个开环系统,无任何反馈环节,这种结构使得DDS的频率转换时间极短。
事实上,在DDS的频率控制字改变之后,需经过一个时钟周期之后按照新的相位增量累加,才能实现频率的转换。
因此,频率时间等于频率控制字的传输,也就是一个时钟周期的时间。
时钟频率越高,转换时间越短。
DDS的频率转换时间可达纳秒数量级,比使用其它的频率合成方法都要短数个数量级。
(3)频率分辨率极高若时钟fs的频率不变,DDS的频率分辨率就是则相位累加器的位数N决定。
只要增加相位累加器的位数N即可获得任意小的频率分辨率。
目前,大多数DDS的分辨率在1Hz数量级,许多小于1mHz甚至更小。
(4)相位变化连续改变DDS输出频率,实际上改变的每一个时钟周期的相位增量,相位函数的曲线是连续的,只是在改变频率的瞬间其频率发生了突变,因而保持了信号相位的连续性。
(5)输出波形的灵活性只要在DDS内部加上相应控制如调频控制FM、调相控制PM和调幅控制AM,即可以方便灵活地实现调频、调相和调幅功能,产生FSK、PSK、ASK和MSK等信号。
另外,只要在DDS的波形存储器存放不同波形数据,就可以实现各种波形输出,如三角波、锯齿波和矩形波甚至是任意的波形。
当DDS的波形存储器分别存放正弦和余弦函数表时,既可得到正交的两路输出。
(6)其他优点由于DDS中几乎所有部件都属于数字电路,易于集成,功耗低、体积小、重量轻、可靠性高,且易于程控,使用相当灵活,因此性价比极高。
缺点:
DDS也有局限性,主要表现在:
(1)输出频带范围有限由于DDS内部DAC和波形存储器(ROM)的工作速度限制,使得DDS输出的最高频有限。
目前市场上采用CMOS、TTL、ECL工艺制作的DDS工习片,工作频率一般在几十MHz至400MHZ左右。
采用GaAs工艺的DDS芯片工作频率可达2GHz左右。
(2)输出杂散大由于DDS采用全数字结构,不可避免地引入了杂散。
其来源主要有三个:
相位累加器相位舍位误差造成的杂散;幅度量化误差(由存储器有限字长引起)造成的杂散和DAC非理想特性造成的杂散。
第2章系统总体设计
2.1 设计思路
采用原理图与VHDL语言结合的方法完成整个系统的设计,其中,PULSE为数控分频模块,包括一个时钟输入、一个4位的数控值输入和一个频率输出,输出的频率用于递增锯齿波、递减锯齿波、三角波、占空比可调方波、正弦波和标准方波、振幅键控、移频键控、移相键控、任意波的时钟输入,以实现各信号的频率调节。
r_zeng为递增锯齿波,其设计方法是每一次时钟信号出现上升沿,则给输出信号加1,直到输出信号为全1,此时将输出信号清零。
Left_zeng为递减锯齿波,其设计方法是每一次时钟信号出现上升沿,则给输出信号减1,直到输出信号为0,此时将输出信号置为全1。
sanjiaobo为三角波发生器,其设计方法是以一个信号a控制,当a为0时,每一次时钟信号出现上升沿,则给输出信号加1,当a为1时,每一次时钟信号出现上升沿,则给输出信号减1,a由输出信号的值控制,当输出信号为全1时,给a置1,当输出信号为0时,给a清0。
Square_ketiao为占空比可调方波,其设计方法是在标准方波的基础上,引入两个调节按键up和down,以增加和减小方波的占空比,在这两个按键的设计上,采用了上升沿和下降沿的判断方式,以调节控制变量z的大小,最后完成占空比的调节。
sine为正弦波,其设计方法是设计一个正弦波的数据表和一个控制变量tmp,时钟上升沿控制tmp的增加,tmp对应正弦数据表中的相应数据。
square为标准方波,其设计方法同占空比可调的方波,只是它的控制变量是一个恒定值,使其占空比为50%。
图2 系统框架
2.2 系统设计
2.2.2 各底层文件管脚图
根据给出的系统原理图,下面分别列出各底层文件管脚图。
数控分频器如图4所示:
图3 数控分频器管脚
其中,CLK为外部输入时钟,D[3..0]为数控分频的计数值输入端,FOUT为分频频率输出。
多路选择器如图5所示:
图4 多路选择器
其中,CLK为外部输入时钟, SEL为多路选择器的选择输入信号,D0-D5为6路信号的输入,Q[7..0]为频率输出,各波形产生器如图6所示:
图5 各波形发生器管脚
其中,CLK为分频后的时钟信号输入端, Q[7..0]为输出的一个8位数据,供DAC0832的数据输入。
第3章程序设计与分析
3.1 程序设计概要
本课程设计主要完成与任意波形信号发生相关的VHDL语言程序设计与控制综合,体现了VHDL从顶向下的设计思想,同时对初学者来说也是一个不错的练习机会。
从整体设计上将要产生的几个波形分开设计,与C语言设计有点类似,不过VHDL语言作为一种硬件描述语言,其本质与C语言不同,它完成的是实际的硬件电路的配置,而C语言完成的是控制、运算等。
3.2 核心程序分析
3.2.1 数控分频器
P_REG:
PROCESS(CLK)
VARIABLECNT8:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
IFCLK'EVENTANDCLK='1'THEN
IFCNT8="1111"THEN
CNT8:
=D;
FULL<='1';
ELSE
CNT8:
=CNT8+1;
FULL<='0';
ENDIF;
ENDIF;
ENDPROCESSP_REG;
以D为基数的一个计数器,时钟上升沿触发,当CNT8=“1111”时给CNT8载入初值,同时给FULL一个时钟周期的高电平,使其周期性的输出一个脉冲信号。
P_DIV:
PROCESS(FULL)
VARIABLECNT2:
STD_LOGIC;
BEGIN
IFFULL'EVENTANDFULL='1'THEN
CNT2:
=NOTCNT2;
IFCNT2='1'THEN FOUT<='1';
ELSE FOUT<='0';
ENDIF;
ENDIF;
ENDPROCESSP_DIV;
此进程应用上一进程的FULL为敏感变量,每次FULL来一个正脉冲时,CNT2取反,再用CNT2来控制FOUT输出。
3.2.2 多路选择器
process(sel)
begin
case sel is
when"0000"=>out_bo<=sine;--输出正弦波
when"0001"=>out_bo<=square;--输出标准方波
when"0010"=>out_bo<=square_ketiao;--输出占空比可调方波
when"0011"=>out_bo<=ask;--输出振幅键控
when"0100"=>out_bo<=fsk;--输出移频键控
when"0101"=>out_bo<=psk;--输出移相键控
when"0110"=>out_bo<=left_zeng;--输出递减锯齿波
when"0111"=>out_bo<=r_zeng;--输出递增锯齿波
when"1000"=>out_bo<=randbo_gnt;--输出任意波形
when"1001"=>out_bo<=jiedi;--输出阶梯波
when"1010"=>out_bo<=sanjiaobo;--输出三角波
whenothers=>out_bo<=null;--其他情况下无输出
endcase;
endprocess;
此进程为一个case语句设计的多路选择器进程,其中,sel为选择哪一种波形的输出。
3.2.3 三角波生成器
PROCESS(clk,reset)
VARIABLE tmp:
STD_LOGIC_VECTOR(7DOWNTO0);
VARIABLE a:
STD_LOGIC;
BEGIN
IFreset='0'THEN
tmp:
="00000000";--复位信号为0,置最小值
ELSIF clk'EVENT AND clk='1'THEN--检测时钟上升沿
IFa='0'THEN
IF tmp=""THEN
tmp:
="";--置最大值
a:
='1';
ELSE --不是最大值时递增
tmp:
=tmp+1;--递增运算
ENDIF;
ELSE
IF tmp ="00000001"THEN
tmp:
="00000000";--置最小值
a:
='0';
ELSE --a为1时,执行递减运算
tmp:
=tmp-1;--递减运算
ENDIF;
ENDIF;
ENDIF;
q<=tmp;
ENDPROCESS;
此进程是控制一个三角波发生的,其中以a作为计满标志。
当tmp为“00000001”时a=0,下一时钟到来时,进入tmp加状态;当tmp为“”时,a=1,下一时钟到来时,进入tmp减状态。
3.2.4 可调节占空比的方波
process(clk,conup,condown),此进程与多路选择器相类似,这里不再最赘述。
PROCESS(clk,clr)
VARIABLE cnt:
INTEGER;--定义内部整数变量
BEGIN
IF clr='0'THEN
a<='0';
ELSIF clk'EVENT AND clk='1'THEN--检测时钟上升沿
cnt:
=cnt+1;--计数
IF cnt a<='1';
ELSif cnt<128then
a<='0';
ELSE
cnt:
=0;
ENDIF;
ENDIF;
ENDPROCESS;
此进程是通过a的值调整一个占空比的信号的控制量。
其中,时钟上升沿条件下,调节a的值,以控制clk的分频系数。
PROCESS(clk,a)
BEGIN
IF clk'EVENT AND clk='1'THEN
IFa='1'THEN
q<=255;--a=1,输出一个波形周期内的高电平
ELSE
q<=0;--a=0,输出一个波形周期的低电平。
ENDIF;
ENDIF;
ENDPROCESS;
此进程是一个分频进程,其时钟来源是实验箱中的时钟源,记满后清零,重新仿真。
ShiftKeying)
主要程序如下
process(yin)—根据输入的信号进行调制
begin
caseyinis
when'1'=> outdata_buf<=indata_buf;--如果输入的是1的话就直接输出正弦波发生器产生的正弦信号,0的话就输出中间状态。
when'0'=> outdata_buf<="";
whenothers=>outdata_buf<=null;--其他情况下则无输出
endcase;
endprocess;
outdata<=outdata_buf;--信号赋值
indata_buf<=indata;
ShiftKeying)
主要是通过分频来实现FSK的,当输入信号为1的时候则对系统输入时钟进行4分频,当输入为0的时候则直接输出输入的时钟信号。
然后将控制输出的时钟信号输到正弦波发生器的时钟脚。
从而实现调频的目的。
process(clk,xuanze)
variablecount:
integerrange0to4;
begin
if clk'event and clk='1'then
if xuanze='1'then—如果输入信号是1的话则进行4分频
ifcount=4then—四分频进程
count:
=0;
full<='1';
else
count:
=count+1;
full<='0';
endif;
elsif xuanze='0'then
full<=notfull;
endif;
endif;
endprocess;
outclk<=full;
ShiftKeying)
PSK实现主要根据输入信号进行判断,如果是0的话那么就将相位移动180度,这个是由255减去正弦波输入的幅度值来实现的,如果输入的是1的话就是直接和载波相位相同,直接输出正弦波信号。
process(pskin)
begin
if clk'event and clk='1'then
if pskin='0'then
outdata<=255-indata;
elsif pskin='1'then
outdata<=indata;
endif;
endif;
endprocess;
任意波的产生主要是先将波的幅度值先存入randbo.mif文件当中,然后再定制一个ROM存储randbo.mif文件中的内容,最后在由相位累加器地址取出对应的幅度值输出到DAC0832的数据口再经过DA转换成模拟信号从而实现任意波的产生。
正弦波我没有使用ROM定制的方法,因为前面试过使用ROM定制结果导致资源占用太大超出了芯片的容量。
所以我后面改用了一个周期的正弦波采样64个点
。
PROCESS(clk,en)
VARIABLE tmp:
INTEGER RANGE 0TO63;
BEGIN
IF clk'EVENT AND clk='1'THEN
ifen='1'then
IF tmp=63THEN
tmp:
=0;
ELSE
tmp:
=tmp+1;
ENDIF;
CASE tmp IS
WHEN00=>q<=255;WHEN01=>q<=254;WHEN02=>q<=252;
WHEN03=>q<=249;WHEN04=>q<=245;WHEN05=>q<=239;
WHEN06=>q<=233;WHEN07=>q<=225;WHEN08=>q<=217;
WHEN09=>q<=207;WHEN10=>q<=197;WHEN11=>q<=186;
WHEN12=>q<=174;WHEN13=>q<=162;WHEN14=>q<=150;
WHEN15=>q<=137;WHEN16=>q<=124;WHEN17=>q<=112;
WHEN18=>q<=99;WHEN19=>q<=87;WHEN20=>q<=75;
WHEN21=>q<=64;WHEN22=>q<=53;WHEN23=>q<=43;
WHEN24=>q<=34;WHEN25=>q<=26;WHEN26=>q<=19;
WHEN27=>q<=13;WHEN28=>q<=8; WHEN29=>q<=4;
WHEN30=>q<=1; WHEN31=>q<=0; WHEN32=>q<=0;
WHEN33=>q<=1; WHEN34=>q<=4; WHEN35=>q<=8;
WHEN36=>q<=13;WHEN37=>q<=19;WHEN38=>q<=26;
WHEN39=>q<=34;WHEN40=>q<=43;WHEN41=>q<=53;
WHEN42=>q<=64;WHEN43=>q<=75;WHEN44=>q<=87;
WHEN45=>q<=99;WHEN46=>q<=112;WHEN47=>q<=124;
WHEN48=>q<=137;WHEN49=>q<=150;WHEN50=>q<=162;
WHEN51=>q<=174;WHEN52=>q<=186;WHEN53=>q<=197;
WHEN54=>q<=207;WHEN55=>q<=217;WHEN56=>q<=225;
WHEN57=>q<=233;WHEN58=>q<=239;WHEN59=>q<=245;
WHEN60=>q<=249;WHEN61=>q<=252;WHEN62=>q<=254;
WHEN63=>q<=255;
WHENOTHERS=>NULL;
ENDCASE;
else tmp:
=0;
endif;
ENDIF;
ENDPROCESS;
第4章仿真与测试