DDS实验报告.docx

上传人:b****6 文档编号:7029150 上传时间:2023-01-16 格式:DOCX 页数:14 大小:749.10KB
下载 相关 举报
DDS实验报告.docx_第1页
第1页 / 共14页
DDS实验报告.docx_第2页
第2页 / 共14页
DDS实验报告.docx_第3页
第3页 / 共14页
DDS实验报告.docx_第4页
第4页 / 共14页
DDS实验报告.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

DDS实验报告.docx

《DDS实验报告.docx》由会员分享,可在线阅读,更多相关《DDS实验报告.docx(14页珍藏版)》请在冰豆网上搜索。

DDS实验报告.docx

DDS实验报告

设计要求说明

1.设计内容

本实验的内容是使用DDS的方法设计一个任意频率的正弦信号发生器,利用Quartus

编辑、编译、综合、适配、仿真测试等工作,并绑定管脚进行硬件测试,最后通过嵌入式逻辑分析仪观察输出信号波形,并验证波形正确以后,再接入DA进行最终模拟输出。

2.设计目的

1、进一步熟悉QuartusⅡ的软件使用方法;

2、熟悉利用VHDL设计数字系统并学习LPMROM的使用方法;

3、学习FPGA硬件资源的使用和控制方法;

4、掌握DDS基本原理,学习利用此原理进行信号发生器的设计。

3.设计要求

基本要求:

1、完成8位输出数据宽度的频率可调的移相正弦信号发生器。

提高部分:

2、完成8位输出数据宽度的移相三角波、方波信号发生器。

3、波形发生器实现幅度可调。

 

基本原理

直接数字频率合成器(DDS)是通信系统中常用到的部件,利用DDS可以制成很有用的信号源。

与模拟式的频率锁相环PLL相比,它有许多优点,突出为

(1)频率的切换迅速;

(2)频率稳定度高。

一个直接数字频率合成器由相位累加器、波形ROM、D/A转换器和低通滤波器构成。

DDS的原理框图如下所示:

图1直接数字频率合成器原理图

其中K为频率控制字,fc为时钟频率,N为相位累加器的字长,D为ROM数据位及D/A转换器的字长。

相位累加器在时钟fc的控制下以步长K作为累加,输出N位二进制码作为波形ROM的地址,对波形ROM进行寻址,波形ROM输出的幅码S(n)经D/A转换器变成梯形波S(t),再经低通滤波器平滑后就可以得到合成的信号波形了。

合成的信号波形形状取决于波形ROM中存放的幅码,因此用DDS可以产生任意波形。

本设计中直接利用D/A转换器得到输出波形,省略了低通滤波器这一环节。

1、频率预置与调节电路

不变量K被称为相位增量,也叫频率控制字。

DDS方程为:

f0=fcK/2n,f0为输出频率,fc为时钟频率。

当K=1时,DDS输出最低频率(也既频率分辩率)为fc/2n

DDS的最大输出频率由Nyguist采样定理决定,即fc/2,也就是说K的最大值为2n-1.因此,只要N足够大,DDS可以得到很细的频率间隔。

要改变DDS的输出频率,只要改变频率控制字K即可。

2、累加器

相位累加器的原理图如下图

 

图2相位累加器原理图

相位累加器由N为加法器与N位寄存器级联构成。

每来一个时钟脉冲fc,加法器将频率控制字与寄存器输出的累加相位数据相加,再把相加后的结果送至寄存器的数据输入端,寄存器将加法器在上一个时钟作用后所产生的下数据反馈到加法器的输入端;以使加法器在下一个时钟作用下继续频率控制字进行相加。

这样,相位累加器在时钟的作用下,进行相位累加,当相位累加器累加满量时,就产生一次溢出,完成一个周期性的动作,这个周期应为uk=2n/GCD(2N;k),其中GCD表示最大公约数。

3、波形存储器

用相位累加器输出的数据作为波形存储器的取样地址进行波形的相位——幅值转换,即可在给定的时间上确定输出的波形的抽样幅值。

N位的寻址ROM相当于把00---3600的正弦信号离散成具有2n样值的序列,若波形ROM有D位数据位,则2n个样值的幅值以D位二进制数值固化在ROM中,按照地址的不同可以输出相宜相位的正弦信号的幅值。

相位----幅值变换原理图如下所示。

 

图3相位-幅度变换原理图

4、D/A转换器

D/A转换器的作用是把已经合成的正弦波的数字量转换成模拟量,正弦幅度量化序列S(n)经D/A转换后变成了包络为正弦波的阶梯波S(t),S(t)的周期为T=uk*Tc.。

需要注意的是,频率合成器对D/A转换器的分辨率有一定的要求,D/A转换器的分辨率越高,合成的正弦波S(t)台阶数就越多,输出波形的精度也就越高。

DDS工作流程示意图:

采用DDS方式的波形发生器:

实验内容

一、按照各功能模块分别编写各功能模块的VHDL文件

10位累加器:

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITYADDER10BIS

PORT(A:

INSTD_LOGIC_VECTOR(9DOWNTO0);

B:

INSTD_LOGIC_VECTOR(9DOWNTO0);

S:

OUTSTD_LOGIC_VECTOR(9DOWNTO0)

);

ENDADDER10B;

ARCHITECTUREbehavOFADDER10BIS

BEGIN

S<=A+B;

ENDbehav;

10位寄存器:

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

ENTITYREG10BIS

PORT(Load:

INSTD_LOGIC;

DIN:

INSTD_LOGIC_VECTOR(9DOWNTO0);

DOUT:

OUTSTD_LOGIC_VECTOR(9DOWNTO0)

);

ENDREG10B;

ARCHITECTUREbehavOFREG10BIS

BEGIN

PROCESS(Load,DIN)

BEGIN

IFLoad'EVENTANDLoad='1'THEN

DOUT<=DIN;

ENDIF;

ENDPROCESS;

ENDbehav;

32位累加器:

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITYADDER32BIS

PORT(A:

INSTD_LOGIC_VECTOR(31DOWNTO0);

B:

INSTD_LOGIC_VECTOR(31DOWNTO0);

S:

OUTSTD_LOGIC_VECTOR(31DOWNTO0)

);

ENDADDER32B;

ARCHITECTUREbehavOFADDER32BIS

BEGIN

S<=A+B;

ENDbehav;

32位寄存器:

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

ENTITYREG32BIS

PORT(Load:

INSTD_LOGIC;

DIN:

INSTD_LOGIC_VECTOR(31DOWNTO0);

DOUT:

OUTSTD_LOGIC_VECTOR(31DOWNTO0)

);

ENDREG32B;

ARCHITECTUREbehavOFREG32BIS

BEGIN

PROCESS(Load,DIN)

BEGIN

IFLoad'EVENTANDLoad='1'THEN

DOUT<=DIN;

ENDIF;

ENDPROCESS;

ENDbehav;

 

然后通过顶层文件将各功能模块用例化语句连接起来

顶层文件:

LIBRARYIEEE;

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITYDDS_VHDLIS

PORT(CLK:

INSTD_LOGIC;

FWORD:

INSTD_LOGIC_VECTOR(7DOWNTO0);

PWORD:

INSTD_LOGIC_VECTOR(7DOWNTO0);

FOUT:

OUTSTD_LOGIC_VECTOR(9DOWNTO0);

POUT:

OUTSTD_LOGIC_VECTOR(9DOWNTO0));

END;

ARCHITECTUREoneOFDDS_VHDLIS

COMPONENTREG32B

PORT(LOAD:

INSTD_LOGIC;

DIN:

INSTD_LOGIC_VECTOR(31DOWNTO0);

DOUT:

OUTSTD_LOGIC_VECTOR(31DOWNTO0));

ENDCOMPONENT;

COMPONENTREG10B

PORT(LOAD:

INSTD_LOGIC;

DIN:

INSTD_LOGIC_VECTOR(9DOWNTO0);

DOUT:

OUTSTD_LOGIC_VECTOR(9DOWNTO0));

ENDCOMPONENT;

COMPONENTADDER32B

PORT(A:

INSTD_LOGIC_VECTOR(31DOWNTO0);

B:

INSTD_LOGIC_VECTOR(31DOWNTO0);

S:

OUTSTD_LOGIC_VECTOR(31DOWNTO0));

ENDCOMPONENT;

COMPONENTADDER10B

PORT(A:

INSTD_LOGIC_VECTOR(9DOWNTO0);

B:

INSTD_LOGIC_VECTOR(9DOWNTO0);

S:

OUTSTD_LOGIC_VECTOR(9DOWNTO0));

ENDCOMPONENT;

COMPONENTdata_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

F32B(27DOWNTO20)<=FWORD;F32B(31DOWNTO28)<="0000";

F32B(19DOWNTO0)<="00000000000000000000";

P10B(9DOWNTO2)<=PWORD;

P10B(1DOWNTO0)<="00";

u1:

ADDER32BPORTMAP(A=>F32B,B=>D32B,S=>DIN32B);

u2:

REG32BPORTMAP(DOUT=>D32B,DIN=>DIN32B,LOAD=>CLK);

u3:

data_romPORTMAP(address=>SIN10B,q=>FOUT,inclock=>CLK);

u4:

ADDER10BPORTMAP(A=>P10B,B=>D32B(31DOWNTO22),S=>LIN10B);

u5:

REG10BPORTMAP(DOUT=>SIN10B,DIN=>LIN10B,LOAD=>CLK);

u6:

data_romPORTMAP(address=>D32B(31DOWNTO22),q=>POUT,inclock=>CLK);

END;

用C语言编写一个sin函数发生器,生成相应的mif文件以保存在ROM中供扫描采样来生成相应的sin波形。

C源程序:

#include

#include"math.h"

main()

{

inti;floats;

FILE*fp;

fp=fopen("data_rom.mif","w");

fprintf(fp,"WIDTH=10;\nDEPTH=1024;\n\nADDRESS_RADIX=UNS;\nDATA_RADIX=UNS;\n\n");

fprintf(fp,"CONTENTBEGIN\n\n");

for(i=0;i<1024;i++)

{

s=sin(atan

(1)*8*i/1024);

fprintf(fp,"%d:

%d;\n",i,(int)((s+1)*1023/2));

}

二、在QuartusⅡ中通过将data_rom.mif文件导入ROM中来定制ROM文件,然后新建项目工程将所有功能模块VHDL文件导入,编译至没有错误,新建波形文件进行波形仿真。

波形仿真图如下:

将仿真输出数据对应mif文件数据,观察若输出数据与对应mif文件中数据一致时,则可以进行嵌入式逻辑分析仪仿真,通过设置参数,将对应文件下载到目标芯片后,运行观察输出波形是否为正弦波。

其输出波形如下:

通过改变频率控制字可改变正弦波频率,改变频率后的波形图如下:

输出频率测量及误差分析

理论值:

3、在原有程序及mif文件的基础上增加三角波函数发生器和方波函数发生器来实现三种波形的输出切换。

通过C编写一个新的波形文件来产生正弦波,三角波和方波,三种波形各取256个数据,这样可以在不增大原有取样数量的基础上同过按键控制访问ROM单元的地址来达到输出不同波形的基础。

C发生函数:

#include

#include"math.h"

main()

{

inti;floats;

FILE*fp;

fp=fopen("wave_rom10.mif","w");

fprintf(fp,"WIDTH=10;\nDEPTH=1024;\n\nADDRESS_RADIX=UNS;\nDATA_RADIX=UNS;\n\n");

fprintf(fp,"CONTENTBEGIN\n\n");

for(i=0;i<256;i++)

{

s=sin(atan

(1)*8*i/256);

fprintf(fp,"%d:

%d;\n",i,(int)((s+1)*255/2));

}

for(i=0;i<256;i++)

{

if(i>=0&&i<=64)

s=1/64.0*i;

elseif(i>64&&i<=192)

s=2-1/64.0*i;

elseif(i>193&&i<=255)

s=1/64.0*i-4;

fprintf(fp,"%d:

%d;\n",i+256,(int)((s+1)*255/2));

}

for(i=0;i<256;i++)

{

if(i>=0&&i<=127)

s=1;

elseif(i>128&&i<=255)

s=-1;

fprintf(fp,"%d:

%d;\n",i+516,(int)((s+1)*255/2));

}

fprintf(fp,"END;");

fclose(fp);

}

在VHDL头文件中通过增加按键程序来控制ROM地址的访问:

CASEKIS

WHEN"00"=>C(1DOWNTO0)<="00";

WHEN"01"=>C(1DOWNTO0)<="01";

WHEN"10"=>C(1DOWNTO0)<="10";

WHEN"11"=>C(1DOWNTO0)<="00";

ENDCASE;

增加按键程序后在进行波形仿真和嵌入式逻辑分析仪仿真发现有取值无规律的现象,一直也没找到问题的所在。

仿真波形图:

(三角波取值)

(正弦波取值)

嵌入式逻辑分析仪波形:

遇到的问题及解决方法

由于EDA已经学了将近一个多学期,当初学的知识现在忘得差不多了,所以对于VHDL的编程思维和仿真步骤都有点陌生,加上快到考试了,所以前两天基本是在熟悉VHDL的编程思想和仿真步骤。

在这之后,工作就变得比较简单了,用C生成函数发生器,DDS各模块的编程等很快就完成了,然后就是通过嵌入式逻辑分析仪来通过对硬件的仿真观察波形输出。

后来在做三种波形循环发生器时就卡壳了,不知道该怎样继续下去,取值怎样取,文件的例化该怎样改,刚开始我们想着是不是可以分别编写三种函数的波形发生器将数据存入不同的ROM块中通过访问不同的ROM来实现,不过这在物理上不可能实现,因为FPGA芯片只有一个ROM块,如果写入新的数据就把原来保存的数据擦出了。

后来还是在老师的提醒下想到可以将三种波形数据集成到一个ROM块中,通过按键控制选择访问每种波形所在的地址达到三种波形输出的切换。

但问题也不是那么简单,首先是在程序修改时就遇到了问题,好几个提示错误。

后来在老师的帮助下发现原来我们给输入函数直接赋值了,哎,编程实在是差啊!

后来进行仿真时发现虽然通过按键可以选择不同地址,但取值好像没有什么规律可言,一直也没搞懂是为什么,到现在也是。

收获与感想

经历了一星期EDA课程设计,对QuartusII的使用方法更加熟悉,如宏模块的定制,嵌入式逻辑分析仪的分析,相应参数的改变等等。

在设计DDS的过程中,我也逐渐学会了大型电路系统的一般设计方法:

自顶向下和模块化。

模块化的电路不仅可以使整个系统更加简洁,也可以将此电路直接移植到其他系统中。

当每个模块调试仿真通过后,整体系统只要将个子模块组合即可,十分方便。

这次的设计也帮我重新复习和巩固了上学期数字电路学习过程中的薄弱环节。

如码转换电路、减法器和D触发器等。

这些内容在实际应用中十分重要。

在自己的电路中用过这些电路后,我对它们的工作原理理解得更加深刻。

而且通过这次课程设计我发现和同学之间的相互讨论更能打开一个人的思维,也更加有效率。

不过以后有什么不懂得还是要多问问老师,毕竟不是什么都能完全靠自己思考就能明白的,有时候,老师的指点更加重要。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1