摘要:直接数字频率合成器DDS具有极高的分辨率、频率转换速度快、相位噪声低等优点。以ALTERA公司的CPU软核Nios为基础,利用Quartus II软件和Sopc Builder,采用两级DDS和动态分频法,提高了信号源的精度。采用双口ROM可以很方便的同时输出两路具有一定相位差的信号,而且频率幅度可调。另外着重介绍了怎样用Matlab产生波形幅度数据以及最后的仿真验证。
1 引言
在实际的通信过程中,系统对频率的精度和稳定度都有较高的要求.而且常常需要用到多种不同频率和相位的信号。传统的波形发生器都是由模拟的电路实现,受到硬件电路的限制,不仅产生的波形少,精度低,而且体积大。灵活性差。DDS(Direct DigitalFrequncy Synthesis,直接数字频率合成)的出现为我们提供了一种新选择。DDS是从相位概念出发直接合成所需要波形的一种新的频率合成技术。由于其具有频率转换快、分辨率高、频率合成范围宽、相位噪声低且相位可控制的优点,因此,DDS技术常用于产生频率快、转换速度快、分辨率高、相位可控的信号。目前.市场上已出现许多DDS专用芯片.但是专用芯片有很多局限性,比如控制方式固定,同时只能输出一路信号.而且价格普遍偏高。利用fpga的高速、高性能和可重构性可实现各种比较复杂的调频、调相和调幅功能。
本文介绍设计的DDS信号源应用ALTERA公司的FPGA器件、Quartus II开发环境和NIOS软核等相关的开发工具,采用VHDL语言及SOPC设计思想。采用两级DDS技术设计波形发生器,并且可以同时输出多路不同相位的信号,满足我们实际的需求。
2 DDS原理
基本DDS的结构框图如图1所示。主要由相位累加器、相位调制器、ROM查找表、D/A以及低通滤波器组成。
图1 DDS结构图
频率字和相位字分别控制输出信号的频率和相位。DDS的核心是N位的相位累加器。在时钟脉冲控制下,相位累加器不断对频率控制字K进行累加,将累加器的输出作为读波形存储器ROM的地址,读出波形数据,然后再进行调幅、数模转换、滤波从而得到光滑的波形信号。在整个过程中相位累加器进行的是线性累加,当累加满时便产生溢出,一个周期完成。相位累加器这个产生溢出的频率就是DDS的输出频率。设频率控制字为K,相位累加器为N位,时钟频率为fs。所以合成输出的信号频率fout 是:
fout=(K/2N)fs
当K=1时有最小频率分辨率:Δf=fs/2N
3 设计方案
3.1提高精度实现
在我们的实际应用中往往对频率较小的信号精度要求较高,而对高频率信号的精度则没有那么高的要求。传统的方法就是增加相位累加器的位数N.但N一旦设计好便不可更改,这样便导致了产生的信号精度不能随频率的降低而升高。根据以上的分析在N不变的情况下要提高精度则只有降低时钟fs(很显然这时的输出频率较低)。下面介绍两种降低fs的方法:
第一,动态分频法。设计的信号发生器不但要能产生低频信号同时也能产生高频信号,所以用固定的分频办法降低fs不能达到要求,这就要求我们采用动态分频法。在需要产生较高频率信号的时候选择小的分频比.而在合成低频率信号的时候选择大的分频比。根据预先给定的不同的输出信号频率选择相应的分频比,保证了产生信号的宽频带。
第二,采用两级DDS。第一级合成DDS1产生一定频率的方波并将此方波送给第二次合成DDS2作为时钟输入。其中DDS1的K1可调,保证输出不同的频率,DDS2的K2=1,保证了输出的精度。本次设计采用此方法。
3.2多路输出设计
无论是用专用芯片还是其他设计的DDS产品,同时都只能输出一路信号,而在我们的实际应用中往往同时需要多路相位不同的信号,借助ALTERA公司的Cyclone系列器件.可以很方便的生成双口的ROM,这样使得我们可以同时对ROM的不同单元寻址,从而产生不同相位的信号,调节相位控制器,可以很方便的改变两路信号的相位差。这样设计的DDS框图如图2:
图2多路输出DDS框图
3.3基于Nios的DDS实现
系统的开发包括硬件和软件两部分,硬件部分采用ALTERA公司性价比较高的Cyclone系列FPGA,使用SoPC Builder生成Nios嵌入式处理器。由于本设计中要求信号幅度、相位和频率都可调节,并且能通过LCD实时的显示,利用SoPC Builder生成可裁剪的Nios CPU软核,并添加一些外围设备接口,如作为控制输入的键盘接口:实时显示用的LCD接口;DDS控制接口等。系统硬件框图如图3。
图3 系统总框图
在Cyclone的FPGA中带了一个PLL.这样我们便能很好的控制系统时钟和DDS的时钟.灵活地选择晶振信号源。另外幅度调制采用一个乘法器,运用硬件电路搭建,充分使用内部的LE资源,而且方便、灵活,能达到速度要求。
系统的软件设计主要是键盘扫描程序的编写、LCD显示的控制接口和对DDS的控制.采用C语言编写。而DDS单元则用VHDL硬件描述语言。PLL模块直接使用MegaWizard Plug-in Manager功能同时产生两路不同的时钟输出.一路给DDS,另一路给Nios软核。
由于DDS的结构,产生的波形由ROM查找表的数据决定,所以改变查找表中的数据便得到不同的信号输出,这样可以很方便的产生正弦、余弦、方波,三角波、锯齿波等。在这次设计中,要产生正弦和余弦信号没必要改变查找表的数据,只需要调整相位即可,这就是多路输出不同相位信号最大的优点。
4 Matlab与Quartus接口设计
设计中需要大量的计算,特别是ROM查找表初始化数据的产生,可以借助matlab强大的计算能力。最后的仿真数据也可以用matlab画图直观的观察。
4.1相位幅度变换
由于Cyclone系列的FPGA具有丰富的memory资源,本方案中选用4K的RAM Block构成查找表。在实际的设计中.当我们产生方波的时候则可以直接采用数学计算,没必要构建查找表,从而节约了资源。而产生正弦或余弦信号时,考虑到正弦信号1/4波形对称的性质.只需要存储π/2的正弦采样点,利用数学计算便可以产生2π弧度的正弦波形。这样大大的缩小了ROM.节约了资源。ROM的初始化数据文件为.mif文件。生成该文件可以借助matlab数学工具,先在matlab里生成正弦信号的采样点数据表格,还需要自己添加程序,下面举例说明。
先编写一段m文件程序,这里以产生216X12正弦波π/2幅度值为例。即在π/2的幅度范围内采样65536个点.每个点的值用12位二进制数表示。在matlab里编写的m文件, 保存的文件名为sin_data.mif。
x=0:1:65535;
y=round(2047*sin(pi*x/131072)) +2048; %pi*x/131072的范围为0~/2%改变131072即可改变正弦信号的长度。2048则决定了数据宽度。
fid=fopen('sin_data.mif','W' );
fprinf(fid,'%d:%d;\n' ,x,y);
fclose(fid);
plot(x,y);
grid on
在sin_data.mif中数据的存放格式为:
相位:幅度值;
但是这样的数据表格在Qualtus 4.2里还不能直接调用,需要我们自己编程,加上数据类型申明,其格式如下:
DEPTH =65536;% Memory depth and width are required%
WIDTH = 12; % Enter a decimal number %
ADDRESS_RADIX=DEC; % Address and value radixes are required%
DATA_RADIX =DEC;% Enter BIN,DEC,HEX,OCT,or UNS;unless%
% otherwise specified,radixes=HEX %
--Specify values for addresses, which can be single address
or range
CONTENT
BEGIN
0:2048;
1:2048:
2:2048;
64613:4094;
64614:4095;
END;
4.2 幅度数据的matlab仿真
经过Quartus的综合、波形仿真后,可以得到.vwf波形文件。然后选择File菜单下的Save Current Report Section As,保存类型选择为.tbl。这样便可以得到输出波形的数字幅度序列数据。就可以借助Matlab工具方便的观察波形。.tbl文件的数据存储格式如下:
时间>边沿标志 相位=幅度值;
其中时间单位默认为ns,边沿标志只有一位,其中1表示上升沿,0表示下降沿,地址和幅度值君采用十六进制数表示。用Matlab进行画图时需要我们自己编写m文件程序。我们需要从表格中提取数据,而识别幅度数据的标志就是“=”,所以判断“=”的位置便可将数据提取出来。但在文件前面的说明中有两个“=”,这是我们不需要的,所以编程的时候应该滤除。在这里假设.tbl文件保存路径为:C:\altera\benben\sin.sim.tbl。m文件如下:
fid=fopen('C:\altera\henben\sin.sim.tbl,'r');
yy=fscanf(fid,'%s')
fclose(fid);
aa=fid(yy=='='); %找出“=”的下标
i=0:
for j=1:length(aa)
if yy(aa(j)-1)<='F' %滤除说明中的“=”
i=i+l;
data_hex(i,1)=yy(aa(j)+1);data_hex(i,2)=yy(aa(i)+2);data_hex(i,3)=yy(aa(j))+3);
%取出幅度数据值.数据为十六进制数
end
end
data_dec=hex2dec(data_hex);%将十六进制数转为十进制数
plot(data_dec);
grid on
5 结论
该设计利用Ahera公司的Cyclone FPGA,借助Nios软核设计的信号产生器,采用两级DDS串联.提高了信号的精度,另外提出了提高精度的动态分频法。针对实际需求,采用双口ROM方便的实现了多路不同相位信号的输出 另外介绍了Matlab与Quartus的接口程序的编写,借助Matlab强大的计算能力和画图功能,为我们的设计带来了极大的方便。实验结果表明该设计是行之有效的,具有很大的实用性。
来源:电子工程世界