基于Verilog实现的DDS任意波形发生器(共36页).doc
精选优质文档-倾情为你奉上河海大学计算机与信息学院(常州)课程设计报告 题 目 简易直接数字频率合成器前端设计专业、学号 电科 授课班号 学生姓名 毛石磊 指导教师 单鸣雷 完成时间 2013-6-28 课程设计(报告)任务书(理 工 科 类)、课程设计(报告)题目: 简易直接数字频率合成器(DDS)前端设计 、课程设计(论文)工作内容一、课程设计目标1、培养综合运用知识和独立开展实践创新的能力以及同组之间合作的能力;2、学习直接数字频率合成器(DDS)相关知识,进行系统构架设计、模块划分和算法分析,并使用Verilog HDL设计一简易直接数字频率合成器,要求具有根据输入的控制字的不同输出不同频率的正弦信号的功能;3、能够对分析、测试、解决实际的数字电路问题加深理解,学以致用,增强动手能力,为今后能够独立进行设计工作打下一定的基础;二、研究方法及手段应用1、学习直接数字频率合成器(DDS)相关知识,确定电路需要实现的功能,分别编写各个功能模块,主要有相位累加器模块、正弦查询表模块和主模块;2、利用仿真软件测试各个模块功能的正确性;3、将各模块综合起来,实现整体功能并采用软件验证;三、课程设计预期效果1、完成实验环境搭建;2、完成DDS的功能设计与综合;3、完成modelsim软件仿真,确定程序代码正确性;4、在理论学习和具体实践中达到对DDS的正确理解。学生姓名: 毛石磊 专业年级: 电子科学与技术 2010级摘 要直接数字频率合成技术(Direct Digital Synthesize,DDS)是继直接频率合成技术和锁相式频率合成技术之后的第三代频率合成技术。它采用全数字技术,并从相位角度出发进行频率合成。目前,DDS的设计大多是应用HDL(Hardware Description Language)对其进行逻辑描述,整个设计可以很容易地实现参数改变和设计移植,给设计者带来很大的方便。Verilog HDL就是其中一种标准化的硬件描述语言,它不仅可以进行功能描述,还可以对仿真测试矢量进行设计。此次课程设计只做软件部分,不做硬件实现,而DDS最重要的软件组成模块是相位累加模块和相位幅值转化模块(ROM)。本设计最重要的任务就是就是用verilog HDL编写相位累加模块和ROM表,然后利用modelsim实现模块的综合与仿真,最终实现功能。【关键词】DDS 相位累加 ROM表ABSTRACTDirect Digital frequency synthesis technology (Direct Digital Synthesize, DDS) is the third generation frequency synthesis technology after Direct frequency synthesis technology and phase lock type synthesis technology. It uses the digital technology to achieve frequency synthesis from the phase perspective . At present, the design of DDS mostly applicates HDL (Hardware Description Language) to make the Description logic, and the whole design can easily achieve parameters change and design transplantation, which gives the designer a lot of convenience. Verilog HDL is one of the standardization of the hardware description language, it not only can describe function,it also can describe the simulation test vector.The course design only has the part of software , and the most important part of software components of the DDS is the phase accumulative module and Phase/amplitude transformation module (ROM). The most important task of this design is to use the verilog HDL to write phase accumulate module and ROM table, then use modelsim to complete synthesize and simulation, and finally achieve the function. 【Key words】DDS Phase accumulate ROM table第一章 系统设计第一节 课题目标及总体方案DDS 技术具有频率切换时间短,频率分辨率高,频率稳定度高,输出信号的频率和相位可以快速切换,输出相位可连续,并且在改变时能够保持相位的连续,很容易实现频率、相位和幅度的数字控制。它在相对带宽、频率转换时间、相位连续性、高分辨率以及集成化等一系列性能指标方面远远超过了传统频率合成技术。因此在现代电子系统及设备的频率源设计中,尤其在通信领域,直接数字频率合成器的应用越来越广泛。本组根据查阅了相关的资料后,总结出了要实现DDS需要的几点关键技术:1) rom查找表: 通过实现使用matlab或者C语言等数学工具将所需的波形采样成为一个个离散的点,存储到rom查找表中,以便于通过相位累加的过程得到的地址取得这些采样点。2) 相位累加器:通过送入一个频率控制字(控制相位变化的步长值),在参考时钟的驱动下进行累加,得到地址信号,传递给rom查找表以得到相对应的采样点;还可以通过输入一个相位控制字来调整波形的初始相位,但本组的作品不涉及相位控制。3) 数模转换:由于通过rom查找表得到的信号是离散的采样点,必须通过DA转换器才能变成连续变化的模拟量,同时,由于产生的波形中含有很多高阶的杂波,导致产生的波形会有很多毛刺,通过在DA后加一级低通滤波电路可以滤掉杂波,得到一个比较理想的正弦波。第二节 直接数字频率合成技术简介频率控制是现代通信技术中很重要的一环,能够获得宽带(频率控制范围宽)、快速(转换时间快)、精细(分辨率高)、杂散小(频谱纯)的频率控制信号一直是通信领域中的一个重要研究内容,。直接数字频率合成(DDS)技术是从相位概念出发直接合成所需波形的一种新的频率合成技术,具有频率分辨率高、频率变换速度快、相位可连续线性变化等优点,在基于数字信号处理的现代通信频率控制中已被广泛采用。一、 总体方案实现及系统框图根据以上分析,可以得出本组的系统框图如下所示:在该DDS电路组成上,包括基准时钟、频率累加器、相位累加器、幅度相位转换电路。频率累加器对输入信号进行累加运算,产生频率控制数据,相位累加器对代表频率的M位二进制码进行累加运算,产生后面波形存储器所需的查表地址,幅度相位转换电路实际上就是一个波形存储器,供查表使用,读出数据送人DA转换器和低通滤波器。但是本次课程设计中我们只做前端设计,最后经DA转换器和低通滤波器将波形数据转换成所需要的模拟波形不实现。系统设计原理框图如下:频率控制字M相位寄存器正弦查询表相位累加器+时钟fcfout相位地址图1.1 系统设计原理框图二、直接数字频率合成技术原理相位累加器由位全加器和位累加寄存器级联而成,可对频率控制字的二进制码进行累加运算,是典型的反馈电路。正弦查找表的数据存放在ROM中,内部存有一个时钟脉冲,相位寄存器以步长M递增。相位寄存器的输出结果的高位部分作为正(余)弦查找表的一个周期的正弦波信号的数字幅度信息,每个查找表的地址对应于正弦波中0°360°范围内的一个相位点。查找表把输入的址信息映射成正(余)弦波的数字幅度信号,输出周期性离散正弦信号。 DDS 具体工作过程如下:每来一个时钟脉冲clk,N 位全加器将频率控制数据M 与累加寄存器输出的累加相位数据N 相加,把相加后的结果送至累加寄存器的输入端。累加寄存器一方面将上一时钟周期作用后所产生的新的数据反馈到加法器的输入端,以使加法器在下一时钟的作用下继续与频率控制数据M 相加;另一方面将这个值作为取样地址值送入幅度/相位转换电路,此电路根据取样地址输出相应的波形数据。假设有一个频率为 f 的余弦信号,现以采样频率对该信号进行采样,得到离散序列为: 其中为采样周期。上式对应的相位序列为: 该相位序列的显著特性就是线性,即相邻样值之间的相位增量是一常数,且仅与信号频率 f 有关。由采样定理可以知道输出波形的频率和输入波形的频率必须满以下关系:,为输出信号的频率,为采样信号频率。其中K和M为两个正数,在下面将会讲到。由上式可以知道如果将的相位等分为M份,则频率为的余弦信号以频率采样后,其量化序列的样本之间的量化相位增量为一个可调的值,通过改变K的值可以实现相位以不同的步长值增长。将代入可以得到,这就是还原出来的信号函数表达式它的频率为 这就是直接数字频率合成(DDS)的方程。在实际的DDS中一般取,N为正整数,表示相位累加器的位数。则DDS方程变为:本设计所基于的理论技术就是这些,事实上,现在的DDS普遍都是采用这样的方法来实现的。我们小组查阅了很多相关的文档,其中无一不是采用了类似的查找表的方式实现,所以本小组也采用了该方法。但是在设计时应注意的问题是,根据信号采样的原理可知,输入信号和输出信号的频率必须满足如下关系才能保证采样可恢复:因此,如果相位累器的地址范围为N位(),即采样点为每周期个采样点。则输入的频率控制字最大值为此时输出最大频率为 当K=1时,输出频率为 这就是DDS合成的频率范围。三、系统组成模块简介1、顶层模块顶层模块是系统程序的主模块,它负责将fom查找表、相位累加等模块组装在一起,通过调用的关系使它们组合成为一个有机的整体。在顶层模块中,定义了参考时钟的输入,复位端口,波形输出、频率控制字等。2、相位累加器模块相位累加器是决定系统性能的关键部分,主要是利用频率控制字和相位控制字来累加出寻址地址。相位累加器在基准频率信号clk的控制下以频率控制字data为步长进行累加运算,产生需要的频率控制数据,在时钟的控制下把累加的结果作为波形存储器ROM的地址,实现对波形存储器ROM的寻址。由于相位累加模块通过C语言实现比较容易,故我们没有单独成立一个模块,而是将它集成到了顶层模块的一个always语句块中:case(choose_wave) 2'b00:begin sin_ena <= 1'b1; cos_ena <= 1'b0; sawtooth_ena <= 1'b0; triangle_ena <= 1'b0; if(ADD_B > 256) ADD_B <= 0; /关键代码,实现相位累加的功能 else ADD_B <= ADD_A + ADD_B; end 2'b01:begin cos_ena <= 1'b1; sin_ena <= 1'b0; sawtooth_ena <= 1'b0; triangle_ena <= 1'b0; if(ADD_B > 256) ADD_B <= 0; /关键代码,实现相位累加的功能 else ADD_B <= ADD_A + ADD_B; end 2'b10:begin sin_ena <= 1'b0; cos_ena <= 1'b0; sawtooth_ena <= 1'b1; triangle_ena <= 1'b0; if(ADD_B > 256) ADD_B <= 0; /关键代码,实现相位累加的功能 else ADD_B <= ADD_A + ADD_B; end 2'b11:begin sin_ena <= 1'b0; cos_ena <= 1'b0; sawtooth_ena <= 1'b0; triangle_ena <= 1'b1; if(ADD_B > 256) ADD_B <= 0; /关键代码,实现相位累加的功能 else ADD_B <= ADD_A + ADD_B; end default:begin ADD_B <= 9'b0; sin_ena <= 1'b0; cos_ena <= 1'b0; sawtooth_ena <= 1'b0; triangle_ena <= 1'b0; end endcase在程序中还出现了一个变量(wave_choose)这是一个用来选择所要输出波形的一个变量,通过它可以控制输出的波形种类(正弦波,余弦波,三角波,锯齿波)。但是由于在设计的时候没有考虑到存在负值的影响,导致最后综合的结果不正确,经过询问老师知道修改方法是将rom查找表中所有采样点的电压负值全部抬高,消除负值,但是由于时间的原因没有来得及修改,也不知道方案修改的结果。3、查找表本模块实现的是一个rom存贮器,用于存储采样的波形数据,并提供地址查找的功能。具体实现的过程:1) 首先使用数学工具计算得到波形采样点,生成mif文件2) 导入数据采样点,给每一个采样点分配地址,并提供外部寻址的接口,此过程可以通过Quartas 来辅助完成由于我们组的设计时在modelsim下进行的,modelsim面向的是仿真,它不会产生所谓的“rom”这种实际的电路,所以我们没有采用这样的方法,而是简单的使用case语句来实现。虽然这样也能得到预期的效果,但是它却没有真正的生成一个“rom”,根据我组的综合结果来看,使用case语句生成的是一个与输入相关的复杂的逻辑网络,而不是rom那样有一定规则的电路结构。一下是我们使用C语言产生采样点的程序:void main()int i,j = 0;FILE *fp;fp=fopen("data.txt","w");for(i=0;i<=256;i+)/j=255*sin(2*3.14159/256*i)+0.5;/四舍五入fprintf(fp,"i=%d,tj=%dn",i,j);fclose(fp);第二章 结果与讨论第一节 实验中遇到的问题 本次课设整体来说还是比较简单的,但是还是碰到些难以解决的问题。其中,最大的问题就是综合的结果不正确,我们组就一直卡在那里找不到原因,后来经过老师的查阅才找到原因:我们rom查找表中含有负值,由于Verilog编程经验不足,没有注意到这一点,所以导致了问题的出现。另外还有一些不足的地方,我们的查找表使用的是case语句,不能生成真正的rom;第二,我们没有对查找表做优化,其中存储的是整个波形周期的采样点,其实,对于有一定周期的正弦函数而言,我们只需要存储它的四分之一个周期的数据,然后通过相位翻转等实现整个波形的复原,这样可以节省存储空间,然而我们由于能力有限,不能实现相关文档中所述的方法。第二节 实验结论以上就是本小组查阅资料学习的成果,经过编码,调试后,在modelsim下仿真得到了预期的结果,以下是仿真截图。图2.1 正弦波仿真结果(choose_wave=00)图2.2 余弦波仿真结果(choose_wave=01)图2.3 三角波仿真结果(choose_wave=10)图2.4 锯齿波仿真结果(choose_wave=11)由仿真图可以看出,在modelsim下所有功能都能够正确实现,前仿真顺利实现。后仿真时由于没有综合得到正确的结果,故不贴出仿真结果截图。以下是综合报告。由。于篇幅有限,在这里只能贴出部分报告。1)延时信息*Report : timing -path full -delay max -max_paths 1 -sort_by groupDesign : rom_sinVersion: D-2010.03-SP2Date : Fri Jun 28 15:23:45 2013* Operating Conditions: typical Library: typicalWire Load Model Mode: top Startpoint: wr_data_reg0 (rising edge-triggered flip-flop clocked by CLK_0) Endpoint: wr_data0 (output port clocked by CLK_0) Path Group: CLK_0 Path Type: max Point Incr Path - clock CLK_0 (rise edge) 0.00 0.00 clock network delay (ideal) 0.00 0.00 wr_data_reg0/CK (DFFRHQXL) 0.00 0.00 r wr_data_reg0/Q (DFFRHQXL) 0.23 0.23 r wr_data0 (out) 0.00 0.23 r data arrival time 0.23 clock CLK_0 (rise edge) 5.00 5.00 clock network delay (ideal) 0.00 5.00 output external delay -2.00 3.00 data required time 3.00 - data required time 3.00 data arrival time -0.23 - slack (MET) 2.77 * End Of Report *2)constraint*Report : constraint -verboseDesign : rom_sinVersion: D-2010.03-SP2Date : Fri Jun 28 15:26:02 2013* Startpoint: wr_data_reg0 (rising edge-triggered flip-flop clocked by CLK_0) Endpoint: wr_data0 (output port clocked by CLK_0) Path Group: CLK_0 Path Type: max Point Incr Path - clock CLK_0 (rise edge) 0.00 0.00 clock network delay (ideal) 0.00 0.00 wr_data_reg0/CK (DFFRHQXL) 0.00 0.00 r wr_data_reg0/Q (DFFRHQXL) 0.23 0.23 r wr_data0 (out) 0.00 0.23 r data arrival time 0.23 clock CLK_0 (rise edge) 5.00 5.00 clock network delay (ideal) 0.00 5.00 output external delay -2.00 3.00 data required time 3.00 - data required time 3.00 data arrival time -0.23 - slack (MET) 2.77 Net: n382 max_transition 3.00 - Transition Time 0.39 - Slack 2.61 (MET) Net: n331 max_capacitance 0.16 - Capacitance 0.01 - Slack 0.15 (MET) Design: rom_sin max_area 0.00 - Current Area 7970.05 - Slack -7970.05 (VIOLATED) * End Of Report *3) 面积*Report : areaDesign : rom_sinVersion: D-2010.03-SP2Date : Fri Jun 28 15:25:16 2013* Library(s) Used: typical (File: /apps/library/SMIC018Digital/synopsys/typical.db) Number of ports: 21Number of nets: 370Number of cells: 358Number of references: 26 Combinational area: 7341.Noncombinational area: 628.Net Interconnect area: undefined (No wire load specified) Total cell area: 7970.Total area: undefined* End Of Report *4) 以下是综合后的截图图2.5 综合后的门级网表图2.6综合后的门级网表第三章 心得与体会感觉对于我来说,每次课程设计都是一次学习的机会。因为每次都会遇到一些自己从来没有遇到的问题。可能是由于自己做的东西比较少的缘故吧,碰到的各种反常的情况很有限,导致了自己解决问题的能力也有限。总的来说这次课设还是很有意义的,至少我又碰到一个案例,相信在以后的实践过程中我就会避免再出现这样的问题,这样就可能会更早地实现我想要的结果。这次课设让我又一次加深了对verilog语言的理解,并且在由verilog这种纯软件的东西变成硬件的东西的过程中又对软硬件的工作过程有更深层次的理解。而且我还做了之前verilog课程设计没有接触过的一个流程那就是综合。当我看到自己写的程序编程一个个逻辑门的连接的时候,感觉自己离集成电路又近一步了。参考文献【1】齐怀龙,杨力生 FPGA实现任意波形发生器 万方数据库 文章编号1008-1739(2010)3、4-92-3【2】余鸿洲 哈尔滨理工大学 硕士学位论文 基于DDS技术的函数波形发生器设计 万方数据库 【3】栾佳明,张秀娟 山东科技大学 基于FPGA的可调信号发生器 文章编号1674-6236(2010)05-0095-03附录 源程序在这里给出了主模块和sin函数查找表两个模块,由于它们实现了课设要求的功能,而且另外几个波形的rom查找表与sin查找表类似,就是改了一下采样点的数据,在此由于篇幅限制,就不贴上了。附录1:主模块module DDS( clk, rst, data, choose_wave, we, data_out ); input clk;input rst;input 1:0choose_wave;input we;/load frequency contrl wordinput 8:0 data;/frequencyoutput8:0 data_out;/wave out/rom addressreg 8:0 ADD_A;reg 8:0 ADD_B;reg sin_ena;reg cos_ena;reg sawtooth_ena;reg triangle_ena;reg 8:0data_out;wire 8:0 sine_d;wire 8:0 cosine_d;wire 8:0 sawtooth_d;wire 8:0 triangle_d;wire 8:0 rom_ad;assign rom_ad = ADD_B;always(posedge clk or negedge rst) begin if(!rst) begin ADD_A <= 9'd0; end else case(we) 1'b1 : ADD_A <= data; 1'b0 : ADD_A <= 9'd0; default: ADD_A <= 9'd0; endcaseendalways(posedge clk or negedge rst) begin if(!rst) begin ADD_B <= 9'b0; sin_ena<=1'b0; cos_ena<=1'b0; sawtooth_ena <= 1'b0; triangle_ena <= 1'b0; end else begin case(choose_wave) 2'b00:begin sin_ena <= 1'b1; cos_ena <= 1'b0; sawtooth_ena <= 1'b0; triangle_ena <= 1'b0; if(ADD_B > 256) ADD_B <= 0; else ADD_B <= ADD_A + ADD_B; end 2'b01:begin cos_ena <= 1'b1; sin_ena <= 1'b0; sawtooth_ena <= 1'b0; triangle_ena <= 1'b0; if(ADD_B > 256) ADD_B <= 0; else ADD_B <= ADD_A + ADD_B; end 2'b10:begin sin_ena <= 1'b0;