任意波形发生器ROM查表的设计
作者:徐丹旸 张晓红 王 勇
来源:《现代电子技术》2008年第11期
        摘 要:基于直接数字合成器(DDS)技术设计的任意波形发生器中,ROM查表是DDS模块的一个重要环节,主要用于存储系统的波形数据。介绍使用C语言、Matlab和DSP Builder三种方法生成正弦波、三角波、锯齿波和方波的查表初始化波形数据,并对每一种方法的程序设计、参数设置以及波形仿真都作了详细说明,所有波形数据均在GW48-SOPC开发系统中测试通过。
         
        关键词:直接数字合成器;查表;任意波形发生器;DSP Builder 
        中图分类号:TP311 文献标识码:B
        文章编号:1004-373X(2008)11-172-02 
        Design of Arbitrary Waveform Generator ROM LUT
         
        XU Danyang,ZHANG Xiaohong,WANG Yong 
        (Electronic Information Engineering College,Henan University of Science and Technology,Luoyang,471003,China)
         
        Abstract:In the arbitrary waveform generator based on DDS,ROM LUT is an important element of the DDS module,which is used to store waveform data of the system.In the paper,using three methods,including C language,Matlab and DSP Builder,producing the arbitrary waveform initialization data of the sine wave,the triangular wave,the saw-tooth wave and the square-wave.Programming,parameter setting and waveform simulation are described to every method detailedly.All waveform data are verified by GW48-SOPC development system.
         
        Keywords:DDS;LUT;arbitrary waveform generator;DSP Builder
        1 引 言 
        目前,利用FPGA设计任意波形发生器是经常采用的一种方法,其核心是直接数字频率合成器(DDS)。DDS系统一般包括系统时钟、频率预置与调节电路(频率累加器)、相位累加器、ROM 查表,输出的数据通过外接的D/A转换器和滤波器完成波形输出。此系统中,ROM中波形数据的设计是完成任意波形的关键环节。构成ROM中初始化波形数据文件的格式有两种:Memory Initialization File(.mif)格式和Hexadecimal(Intel-Format)File (.hex) 格式,实际应用中使用其中一种格式的文件即可。本文以图1所示DDS系统为例,采用三种方法生成正弦波、三角波、矩形波和锯齿波的ROM查表。 
        图1 直接数字频率合成器系统
        图1所示系统参数:系统时钟(F CLK )为166.67 MHz(由FPGA时钟50 MHz晶振通过PLL 3分频10倍频得到);频率累加器位宽(N)为24位;相位累加器位宽为 10位 ;ROM表数据位宽为8位;ROM表地址为10位。硬件选用GW48-SOPC开发系统,其目标芯片为Altera公司Cyclone系列EP1C6Q240C8。 
        2 利用C语言生成MIF文件 
        产生正弦波数据的C程序:
         
        #include"stdio.h" 
        #include"math.h" 
matlab中printf输出格式        #define N 1024 
        void main() 
        { 
        FILE *fp; 
        double y; 
        int n; 
        if((fp=fopen("sindata.mif","w"))==NULL) 
        {printf("cannot open this file\\n"); 
        exit(0); 
        } 
        fprintf(fp,"WIDTH=10;\\n"); 
        fprintf(fp,"DEPTH=1024;\\n"); 
        fprintf(fp,"ADDRESSRADIX=DEC;\\n"); 
        fprintf(fp,"DATARADIX=DEC;\\n"); 
        fprintf(fp,"CONTENT BEGIN\\n"); 
        for(n=0;n
        {y=127.5+127.5*sin(n*3.1415926535/128); 
        if(fmod(n,10)==0) 
        {fprintf(fp,"\\n");} 
        fprintf(fp,"%4d:%4.0f;",n,y); 
        } 
        fprintf(fp,"\\nEND;"); 
        fclose(fp); 
        }
         
        在TC环境下运行,在Output文件夹下生成SIN101~1文件,运行此文件得到SINDATA.mif文件。文件内容如下:
         
        WIDTH=10; 
        DEPTH=1024; 
        ADDRESSRADIX=DEC; 
        DATARADIX=DEC; 
        CONTENT BEGIN 
        0:128;1:131;2:134;3:137;4:140;5:143;6:146;7:149;8:152;9:155;10:158;11:162;12:165;13:167;14:170;15:173;16:176;17:179;18:182;19:185; 
        …(略去数据) 
        1020:115;1021:118;1022:121;1023:124; 
        END;
         
        3 用Matlab生成.mif数据文件 
        利用Matlab可以生成.mif文件,但此文件不能直接在定制ROM中使用,可以把Matlab计算出来的数据粘贴到QuartusⅡ中生成.mif文件,以三角波为例说明。 
        图2 Matlab中三角波波形
        Matlab生成三角波数据的程序:
         
        clear 
        clc 
        Fs=1023;%只要1 024个值 
        t=0:0.2/Fs:0.2; 
        x1=round((sawtooth(2*pi*5*t,0.5)+1)/2*255)′;%三角波归一化 
        plot(t,x1),axis([0,0.2,0,255]) 
        len=length(x1)%len=1 024 
        fid= fopen(′d:\\deltarom.mif′,′w′);%为幅度值的存储准备一个文件 
        fprintf(fid,′MEMORYINITIALIZATIONRADIX=16;\\n′); 
        fprintf(fid,′MEMORYINITIALIZATIONVECTOR=\\n′); 
        for i = 1:len%len=1 024 
        fprintf(fid,′%x,\\n′,x1(i));%循环将值写入文件中 
        end 
        fclose(fid);
         
        打开Matlab的Workspace中参量X1, 复制里面生成的1 024个数据。在QuartusⅡ中打开ROM数据文件编辑窗,即File\\New\\Other files\\Memory Initialization File,根据DDS设计要求,设置ROM的数据数Number为 1 024 ,数据宽Word size取8位,把Matlab中的波形数据粘贴入.mif数据表格,保存此数据文件即可。若希望生成其他波形数据,只需修改程序中“x1=round((sawtooth(2*pi*5*t,0.5)+1)/2*255)′”语句即可。 
        4 利用DSP Builder生成波形数据文件 
        利用DSP Builder生成.mif和.hex格式的波形数据文件是最简便的方法。在Matlab的Simulink环境中,用图形方式调用DSP Builder和Simulink库中的图形模块完成设计和仿真,如图3所示。若仿真正确, DSP Builder可直接生成.hex和.mif文件,在其数据文件目录中可以到。只需设置图3中LUT模块参数,就可以改变输出波形类型、幅值和数据文件(.hex或.mif) 大小。 
        图3 利用DSP Builder设计信号发生器
        根据前述设计要求,在LUT参数选项中,Bus Type:Unsigned Integer;Out:8;LUT
Address Wide:10;Matlab Array:127*sawtooth([0:2*pi/(2^10):2*pi],1)+128(锯齿波公式,使用了归一算法,保证波形幅值在0~255之间,便于进行D/A转换)。仿真结果如图4所示。修改Matlab Array中的式子,即可生成正弦波(图5)、方波( 图6 )、三角波。 
        图4 锯齿波仿真波形
        图5 正弦波仿真波形
        图6 方波仿真波形
        正弦波:127*sin( [0:2*pi/(2^10):2*pi] )+128 
        方波:127*square([0:2*pi/(2^10):2*pi],50)+128 
        三角波:127*sawtooth([0:2*pi/(2^10):2*pi],0.5)+128 
        从仿真图中可以看到,输出波形在0~255之间,符合8位D/A转换器DAC0832输入要求。
        5 结 语 
        生成.hex或.mif文件后,就可以定制ROM元件,很多资料中都有详细介绍,这里不再详述。本文介绍的三种方法所生成的波形数据均已在GW48-SOPC开发系统上通过验证,但推荐采用DSP Builder生成数据文件的方法,因该方法不但参数设置简便,而且易于进行仿真验证。总之,不论采用哪种方法生成ROM查表,都要参照系统芯片类型和D/A转换器等硬件资源条件完成设计。