DDS载波发生器

前言

        DDS(Direct Digital Synthesis)载波发生器是一种利用数字合成技术生成波形信号的设备。它可以产生非常精确、稳定的频率信号,广泛应用于信号处理、通信系统、测试和测量等领域。本章节利用IP核rom,设计一能够进行波形切换,频率变化,振幅变化的波形发生器。

正文

一、DDS载波发生器

        1.项目需求

        设计一个能够进行波形切换(正弦波,方波,三角波,锯齿波),频率变化,振幅变化的波形发生器,通过独立按键对这些功能进行控制,利用IP核进行设计。

        2.技术介绍

        假设已经将正弦波数据(256个)存储到rom中,假设利用驱动时钟控制rom地址一个时钟周期变换一次,那么产生的正弦波频率为:1/256*20(ns) =195.3125khz。

如果不能改变驱动时钟频率,如果将产生的正弦波频率增大,控地址在每一次变化加2,只能怪读取128个数据,产生的正弦波频率为:390.625khz,在不改变驱动时钟频率,同时也不能丢失正弦波数据,控制地址两个驱动时钟周期变化一次,那么产生的正弦波频率为:(1/256*20(ns))/ 2 = 97.656khz;

       根据这样的逻辑,产生一个目标频率小于1hz正弦波,假设地址变化一次需要经过256个驱动时钟周期,可以产生一个8位的循环计数器,当其计数到255时rom地址变化一次,就可以将地址和计数器拼接起来形成一个新的计数器,新的计数器的位宽为16位的,高8位表示rom地址,可以得到一个频率为:(1/256*20(ns))/ 2^8 = 762.94hz正弦波。

       产生一个24位的计数器,高8位表示rom地址,那么产生的正弦波频率为:(1/256*20(ns))/ 2^16 =2.98hz

       产生一个26位的计数器,高8位表示rom地址,那么产生的正弦波频率为:(1/256*20(ns))/ 2^18=0.745hz.

       产生一个32位的计数器,高8位表示rom地址,那么产生的正弦波频率为:(1/256*20(ns))/ 2^24=0.0116hz  

        从这里可以看出,用到的计数器位数越多,产生的信号频率越小,频率越小,信号的精确度越高,这里引进一个概念:频率控制字。频率控制字的精度受限于其位数,因此更高位数的控制字可以提供更高的频率分辨率。

       频率控制字:(FCLK系统时钟50Mhz,频率控制字为32位N=32)

假设产生一个10khz的正弦波,频率控制字为:(10khz/50Mhz)*2^32=858993

        1.波形切换

        需要实现四种波形的切换,默认显示的波形为正弦波,切换波形的顺序为:正弦—方波—三角波—锯齿波—正弦,每一个波形数据提取的波形数据宽度为8位,深度为256,通过第三方软件,将四种波形的数据提取出来,合并在一起,形成一个深度为1024,宽度为8的Mif文件。

       第一个正弦波时,地址在0到255变化

       第二个方波时,地址在256到511变化

       第三个三角波时,地址在512到767变化

       第四个锯齿波时,地址在768到1023变化

        利用有限状态机理论进行控制,将每一种波形显示作为一个状态,四个状态的跳转条件为切换按键进行一次操作,状态在跳转的同时,需要将每一个状态开始的初始地址数值给到地址变量。

        2.频率变化

        地址变化控制频率变化的变量addr给到rom_addr,让其rom_addr = addr + (256,512,678)    在控制频率变化变量模块里的频率控制字需要作为变量产生,在没有对波形频率进行控制变化时,默认每一个波形频率为:50khz,每对控制波形频率按键操作一次,频率增加50khz,控制频率最大变化到1mhz,那么频率控制字就有20种变化,通过控制频率按键的操作次数控制产生频率控制字。

        3.振幅变化

       改变振幅改变的是波形数据的大小,不管哪一种波形,其数据大小范围:0到255,在进行波形振幅控制变化时,最大将波形数据范围修改为0到510,每对波形振幅按键进行一次操作时,波形的数据增大32。

制作包含各类波数据的mif文件,调用IP核rom(具体调用方法参考IP核ROM调用

-- Copyright (C) 1991-2013 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions 
-- and other software and tools, and its AMPP partner logic 
-- functions, and any output files from any of the foregoing 
-- (including device programming or simulation files), and any 
-- associated documentation or information are expressly subject 
-- to the terms and conditions of the Altera Program License 
-- Subscription Agreement, Altera MegaCore Function License 
-- Agreement, or other applicable license agreement, including, 
-- without limitation, that your use is for the sole purpose of 
-- programming logic devices manufactured by Altera and sold by 
-- Altera or its authorized distributors.  Please refer to the 
-- applicable agreement for further details.

-- Quartus II generated Memory Initialization File (.mif)

WIDTH=8;
DEPTH=1024;

ADDRESS_RADIX=UNS;
DATA_RADIX=UNS;

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;
	20    :   188;
	21    :   190;
	22    :   193;
	23    :   196;
	24    :   198;
	25    :   201;
	26    :   203;
	27    :   206;
	28    :   208;
	29    :   211;
	30    :   213;
	31    :   215;
	32    :   218;
	33    :   220;
	34    :   222;
	35    :   224;
	36    :   226;
	37    :   228;
	38    :   230;
	39    :   232;
	40    :   234;
	41    :   235;
	42    :   237;
	43    :   238;
	44    :   240;
	45    :   241;
	46    :   243;
	47    :   244;
	48    :   245;
	49    :   246;
	50    :   248;
	51    :   249;
	[52..53]  :   250;
	54    :   251;
	55    :   252;
	[56..57]  :   253;
	[58..60]  :   254;
	[61..67]  :   255;
	[68..70]  :   254;
	[71..72]  :   253;
	73    :   252;
	74    :   251;
	[75..76]  :   250;
	77    :   249;
	78    :   248;
	79    :   246;
	80    :   245;
	81    :   244;
	82    :   243;
	83    :   241;
	84    :   240;
	85    :   238;
	86    :   237;
	87    :   235;
	88    :   234;
	89    :   232;
	90    :   230;
	91    :   228;
	92    :   226;
	93    :   224;
	94    :   222;
	95    :   220;
	96    :   218;
	97    :   215;
	98    :   213;
	99    :   211;
	100   :   208;
	101   :   206;
	102   :   203;
	103   :   201;
	104   :   198;
	105   :   196;
	106   :   193;
	107   :   190;
	108   :   188;
	109   :   185;
	110   :   182;
	111   :   179;
	112   :   176;
	113   :   173;
	114   :   170;
	115   :   167;
	116   :   165;
	117   :   162;
	118   :   158;
	119   :   155;
	120   :   152;
	121   :   149;
	122   :   146;
	123   :   143;
	124   :   140;
	125   :   137;
	126   :   134;
	127   :   131;
	128   :   127;
	129   :   124;
	130   :   121;
	131   :   118;
	132   :   115;
	133   :   112;
	134   :   109;
	135   :   106;
	136   :   103;
	137   :   100;
	138   :   97;
	139   :   93;
	140   :   90;
	141   :   88;
	142   :   85;
	143   :   82;
	144   :   79;
	145   :   76;
	146   :   73;
	147   :   70;
	148   :   67;
	149   :   65;
	150   :   62;
	151   :   59;
	152   :   57;
	153   :   54;
	154   :   52;
	155   :   49;
	156   :   47;
	157   :   44;
	158   :   42;
	159   :   40;
	160   :   37;
	161   :   35;
	162   :   33;
	163   :   31;
	164   :   29;
	165   :   27;
	166   :   25;
	167   :   23;
	168   :   21;
	169   :   20;
	170   :   18;
	171   :   17;
	172   :   15;
	173   :   14;
	174   :   12;
	175   :   11;
	176   :   10;
	177   :   9;
	178   :   7;
	179   :   6;
	[180..181]  :   5;
	182   :   4;
	183   :   3;
	[184..185]  :   2;
	[186..188]  :   1;
	[189..195]  :   0;
	[196..198]  :   1;
	[199..200]  :   2;
	201   :   3;
	202   :   4;
	[203..204]  :   5;
	205   :   6;
	206   :   7;
	207   :   9;
	208   :   10;
	209   :   11;
	210   :   12;
	211   :   14;
	212   :   15;
	213   :   17;
	214   :   18;
	215   :   20;
	216   :   21;
	217   :   23;
	218   :   25;
	219   :   27;
	220   :   29;
	221   :   31;
	222   :   33;
	223   :   35;
	224   :   37;
	225   :   40;
	226   :   42;
	227   :   44;
	228   :   47;
	229   :   49;
	230   :   52;
	231   :   54;
	232   :   57;
	233   :   59;
	234   :   62;
	235   :   65;
	236   :   67;
	237   :   70;
	238   :   73;
	239   :   76;
	240   :   79;
	241   :   82;
	242   :   85;
	243   :   88;
	244   :   90;
	245   :   93;
	246   :   97;
	247   :   100;
	248   :   103;
	249   :   106;
	250   :   109;
	251   :   112;
	252   :   115;
	253   :   118;
	254   :   121;
	255   :   124;
	[256..383]  :   0;
	[384..511]  :   255;
	512   :   0;
	513   :   2;
	514   :   4;
	515   :   6;
	516   :   8;
	517   :   10;
	518   :   12;
	519   :   14;
	520   :   16;
	521   :   18;
	522   :   20;
	523   :   22;
	524   :   24;
	525   :   26;
	526   :   28;
	527   :   30;
	528   :   32;
	529   :   34;
	530   :   36;
	531   :   38;
	532   :   40;
	533   :   42;
	534   :   44;
	535   :   46;
	536   :   48;
	537   :   50;
	538   :   52;
	539   :   54;
	540   :   56;
	541   :   58;
	542   :   60;
	543   :   62;
	544   :   64;
	545   :   66;
	546   :   68;
	547   :   70;
	548   :   72;
	549   :   74;
	550   :   76;
	551   :   78;
	552   :   80;
	553   :   82;
	554   :   84;
	555   :   86;
	556   :   88;
	557   :   90;
	558   :   92;
	559   :   94;
	560   :   96;
	561   :   98;
	562   :   100;
	563   :   102;
	564   :   104;
	565   :   106;
	566   :   108;
	567   :   110;
	568   :   112;
	569   :   114;
	570   :   116;
	571   :   118;
	572   :   120;
	573   :   122;
	574   :   124;
	575   :   126;
	576   :   128;
	577   :   129;
	578   :   131;
	579   :   133;
	580   :   135;
	581   :   137;
	582   :   139;
	583   :   141;
	584   :   143;
	585   :   145;
	586   :   147;
	587   :   149;
	588   :   151;
	589   :   153;
	590   :   155;
	591   :   157;
	592   :   159;
	593   :   161;
	594   :   163;
	595   :   165;
	596   :   167;
	597   :   169;
	598   :   171;
	599   :   173;
	600   :   175;
	601   :   177;
	602   :   179;
	603   :   181;
	604   :   183;
	605   :   185;
	606   :   187;
	607   :   189;
	608   :   191;
	609   :   193;
	610   :   195;
	611   :   197;
	612   :   199;
	613   :   201;
	614   :   203;
	615   :   205;
	616   :   207;
	617   :   209;
	618   :   211;
	619   :   213;
	620   :   215;
	621   :   217;
	622   :   219;
	623   :   221;
	624   :   223;
	625   :   225;
	626   :   227;
	627   :   229;
	628   :   231;
	629   :   233;
	630   :   235;
	631   :   237;
	632   :   239;
	633   :   241;
	634   :   243;
	635   :   245;
	636   :   247;
	637   :   249;
	638   :   251;
	639   :   253;
	640   :   255;
	641   :   253;
	642   :   251;
	643   :   249;
	644   :   247;
	645   :   245;
	646   :   243;
	647   :   241;
	648   :   239;
	649   :   237;
	650   :   235;
	651   :   233;
	652   :   231;
	653   :   229;
	654   :   227;
	655   :   225;
	656   :   223;
	657   :   221;
	658   :   219;
	659   :   217;
	660   :   215;
	661   :   213;
	662   :   211;
	663   :   209;
	664   :   207;
	665   :   205;
	666   :   203;
	667   :   201;
	668   :   199;
	669   :   197;
	670   :   195;
	671   :   193;
	672   :   191;
	673   :   189;
	674   :   187;
	675   :   185;
	676   :   183;
	677   :   181;
	678   :   179;
	679   :   177;
	680   :   175;
	681   :   173;
	682   :   171;
	683   :   169;
	684   :   167;
	685   :   165;
	686   :   163;
	687   :   161;
	688   :   159;
	689   :   157;
	690   :   155;
	691   :   153;
	692   :   151;
	693   :   149;
	694   :   147;
	695   :   145;
	696   :   143;
	697   :   141;
	698   :   139;
	699   :   137;
	700   :   135;
	701   :   133;
	702   :   131;
	703   :   129;
	704   :   128;
	705   :   126;
	706   :   124;
	707   :   122;
	708   :   120;
	709   :   118;
	710   :   116;
	711   :   114;
	712   :   112;
	713   :   110;
	714   :   108;
	715   :   106;
	716   :   104;
	717   :   102;
	718   :   100;
	719   :   98;
	720   :   96;
	721   :   94;
	722   :   92;
	723   :   90;
	724   :   88;
	725   :   86;
	726   :   84;
	727   :   82;
	728   :   80;
	729   :   78;
	730   :   76;
	731   :   74;
	732   :   72;
	733   :   70;
	734   :   68;
	735   :   66;
	736   :   64;
	737   :   62;
	738   :   60;
	739   :   58;
	740   :   56;
	741   :   54;
	742   :   52;
	743   :   50;
	744   :   48;
	745   :   46;
	746   :   44;
	747   :   42;
	748   :   40;
	749   :   38;
	750   :   36;
	751   :   34;
	752   :   32;
	753   :   30;
	754   :   28;
	755   :   26;
	756   :   24;
	757   :   22;
	758   :   20;
	759   :   18;
	760   :   16;
	761   :   14;
	762   :   12;
	763   :   10;
	764   :   8;
	765   :   6;
	766   :   4;
	767   :   2;
	768   :   0;
	769   :   1;
	770   :   2;
	771   :   3;
	772   :   4;
	773   :   5;
	774   :   6;
	775   :   7;
	776   :   8;
	777   :   9;
	778   :   10;
	779   :   11;
	780   :   12;
	781   :   13;
	782   :   14;
	783   :   15;
	784   :   16;
	785   :   17;
	786   :   18;
	787   :   19;
	788   :   20;
	789   :   21;
	790   :   22;
	791   :   23;
	792   :   24;
	793   :   25;
	794   :   26;
	795   :   27;
	796   :   28;
	797   :   29;
	798   :   30;
	799   :   31;
	800   :   32;
	801   :   33;
	802   :   34;
	803   :   35;
	804   :   36;
	805   :   37;
	806   :   38;
	807   :   39;
	808   :   40;
	809   :   41;
	810   :   42;
	811   :   43;
	812   :   44;
	813   :   45;
	814   :   46;
	815   :   47;
	816   :   48;
	817   :   49;
	818   :   50;
	819   :   51;
	820   :   52;
	821   :   53;
	822   :   54;
	823   :   55;
	824   :   56;
	825   :   57;
	826   :   58;
	827   :   59;
	828   :   60;
	829   :   61;
	830   :   62;
	831   :   63;
	832   :   64;
	833   :   65;
	834   :   66;
	835   :   67;
	836   :   68;
	837   :   69;
	838   :   70;
	839   :   71;
	840   :   72;
	841   :   73;
	842   :   74;
	843   :   75;
	844   :   76;
	845   :   77;
	846   :   78;
	847   :   79;
	848   :   80;
	849   :   81;
	850   :   82;
	851   :   83;
	852   :   84;
	853   :   85;
	854   :   86;
	855   :   87;
	856   :   88;
	857   :   89;
	858   :   90;
	859   :   91;
	860   :   92;
	861   :   93;
	862   :   94;
	863   :   95;
	864   :   96;
	865   :   97;
	866   :   98;
	867   :   99;
	868   :   100;
	869   :   101;
	870   :   102;
	871   :   103;
	872   :   104;
	873   :   105;
	874   :   106;
	875   :   107;
	876   :   108;
	877   :   109;
	878   :   110;
	879   :   111;
	880   :   112;
	881   :   113;
	882   :   114;
	883   :   115;
	884   :   116;
	885   :   117;
	886   :   118;
	887   :   119;
	888   :   120;
	889   :   121;
	890   :   122;
	891   :   123;
	892   :   124;
	893   :   125;
	894   :   126;
	895   :   127;
	[896..897]  :   128;
	898   :   129;
	899   :   130;
	900   :   131;
	901   :   132;
	902   :   133;
	903   :   134;
	904   :   135;
	905   :   136;
	906   :   137;
	907   :   138;
	908   :   139;
	909   :   140;
	910   :   141;
	911   :   142;
	912   :   143;
	913   :   144;
	914   :   145;
	915   :   146;
	916   :   147;
	917   :   148;
	918   :   149;
	919   :   150;
	920   :   151;
	921   :   152;
	922   :   153;
	923   :   154;
	924   :   155;
	925   :   156;
	926   :   157;
	927   :   158;
	928   :   159;
	929   :   160;
	930   :   161;
	931   :   162;
	932   :   163;
	933   :   164;
	934   :   165;
	935   :   166;
	936   :   167;
	937   :   168;
	938   :   169;
	939   :   170;
	940   :   171;
	941   :   172;
	942   :   173;
	943   :   174;
	944   :   175;
	945   :   176;
	946   :   177;
	947   :   178;
	948   :   179;
	949   :   180;
	950   :   181;
	951   :   182;
	952   :   183;
	953   :   184;
	954   :   185;
	955   :   186;
	956   :   187;
	957   :   188;
	958   :   189;
	959   :   190;
	960   :   191;
	961   :   192;
	962   :   193;
	963   :   194;
	964   :   195;
	965   :   196;
	966   :   197;
	967   :   198;
	968   :   199;
	969   :   200;
	970   :   201;
	971   :   202;
	972   :   203;
	973   :   204;
	974   :   205;
	975   :   206;
	976   :   207;
	977   :   208;
	978   :   209;
	979   :   210;
	980   :   211;
	981   :   212;
	982   :   213;
	983   :   214;
	984   :   215;
	985   :   216;
	986   :   217;
	987   :   218;
	988   :   219;
	989   :   220;
	990   :   221;
	991   :   222;
	992   :   223;
	993   :   224;
	994   :   225;
	995   :   226;
	996   :   227;
	997   :   228;
	998   :   229;
	999   :   230;
	1000  :   231;
	1001  :   232;
	1002  :   233;
	1003  :   234;
	1004  :   235;
	1005  :   236;
	1006  :   237;
	1007  :   238;
	1008  :   239;
	1009  :   240;
	1010  :   241;
	1011  :   242;
	1012  :   243;
	1013  :   244;
	1014  :   245;
	1015  :   246;
	1016  :   247;
	1017  :   248;
	1018  :   249;
	1019  :   250;
	1020  :   251;
	1021  :   252;
	1022  :   253;
	1023  :   254;
END;

        3.顶层架构

        红色箭头代表clk和rst_n,key_top模块包含三个按键的消抖处理,产生有效信号;ctrl_freq模块产生频率控制字,通过有限状态机将特定频率与状态绑定,通过按键切换状态,生成特定的频率控制字;addr_ctrl模块接收频率控制字产生读取地址;wave_ctrl对读取地址进行处理,通过有限状态机,对地址进行整体移位,进行波形切换;ampl_ctrl模块进行振幅控制,将读取的数据进行并位,倍数处理。

        4.端口描述

clk时钟
rst_n复位按键
key_adjust切换波形按键
key_freq切换频率按键
key_ampl改变振幅按键

二、代码验证

        wave_ctrl模块:对读取地址进行处理,通过有限状态机,对地址进行整体移位,进行波形切换;

module wave_ctrl(

	input clk,
	input rst_n,
	input flag,//波形切换按键有效信号
	input [7:0] addr,//输入的ROM地址
	
	output reg [9:0] rom_addr//输出的ROM地址
);

reg [1:0] state;
parameter s0 = 2'd0;//  正弦[  0: 255]
parameter s1 = 2'd1;//  方波[256: 511]
parameter s2 = 2'd2;//三角弦[512: 767]
parameter s3 = 2'd3;//锯齿弦[768:1023]

always @(posedge clk,negedge rst_n)//状态机进行地址切换
begin
	if(rst_n == 0)
		begin
			state <= s0;
			rom_addr <= 10'd0;
		end 
	else
		case(state)
			s0	:	begin
						if(flag == 1)
							begin
								state <= s1;
								rom_addr <= addr;
							end 
						else 
							begin 
								state <= s0
								rom_addr <= addr;
							end 
					end 
			s1	:	begin
						if(flag == 1)
							begin
								state <= s2;
								rom_addr <= addr + 10'd256;
							end 
						else 
							begin 
								state <= s1;
								rom_addr <= addr + 10'd256;
							end 
					end 
			s2	:	begin
						rom_addr <= addr + 10'd512;
						if(flag == 1)
							state <= s3;
						else
							state <= s2;
					end 
			s3	:	begin
						rom_addr <= addr + 10'd768;
						if(flag == 1)
							state <= s0;
						else
							state <= s3;
					end 		
			default	:	begin state <= s0; rom_addr <= 10'd0;end 
		endcase
end 

endmodule 

        ctrl_freq模块:产生频率控制字,通过有限状态机将特定频率与状态绑定,通过按键切换状态,生成特定的频率控制字

module ctrl_freq(

	input clk,
	input rst_n,
	input flag,//频率切换按键有效信号
	
	output reg [31:0] fword//产生的频率控制字
);

reg [4:0] cnt;

always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		cnt <= 5'd0;
	else
		if(flag == 1)
			if(cnt < 19)
				cnt <= cnt + 5'd1;
			else 
				cnt <= 5'd0;
		else 
			cnt <= cnt;
end 

always @(*) begin
	if(rst_n == 0)
		fword <= 32'd0;
	else
		case(cnt)
			5'd0	:	fword <= 32'd4294967;//50khz
			5'd1	:	fword <= 32'd8589935;//100khz
			5'd2	:	fword <= 32'd12884902;//150khz
			5'd3	:	fword <= 32'd17179869;//200khz
			5'd4	:	fword <= 32'd21474836;//250khz
			5'd5	:	fword <= 32'd25769804;//300khz
			5'd6	:	fword <= 32'd30064771;//350khz
			5'd7	:	fword <= 32'd34359738;//400khz
			5'd8	:	fword <= 32'd38654706;//450khz
			5'd9	:	fword <= 32'd42949673;//500khz
			5'd10	:	fword <= 32'd47244640;//550khz
			5'd11	:	fword <= 32'd51539608;//600khz
			5'd12	:	fword <= 32'd55834575;//650khz
			5'd13	:	fword <= 32'd60129542;//700khz
			5'd14	:	fword <= 32'd64424509;//750khz
			5'd15	:	fword <= 32'd68719477;//800khz
			5'd16	:	fword <= 32'd73014444;//850khz
			5'd17	:	fword <= 32'd77309411;//900khz
			5'd18	:	fword <= 32'd81604379;//950khz
			5'd19	:	fword <= 32'd85899346;//1mhz
			default	:	fword <= 32'd0;
		endcase
end 

endmodule 

        addr_ctrl模块:接收频率控制字产生读取地址;

module addr_ctrl(

	input clk,
	input rst_n,
	input [31:0] fword,//频率控制字
	
	output [7:0] addr//ROM需要的地址
);

reg [31:0] cnt;
always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		cnt <= 32'd0;
	else
		cnt <= cnt + fword;
end  

assign addr = cnt[31:24];

endmodule 

        ampl_ctrl模块:进行振幅控制,将读取的数据进行并位,倍数处理。

module ampl_ctrl(

	input clk,
	input rst_n,
	input flag,
	input [7:0] data,//ROM读出的数据
	
	output reg [8:0] wave//并位后的数据
);

reg [3:0] cnt;

always @(posedge clk,negedge rst_n)//状态转换条件
begin
	if(rst_n == 0)
		cnt<= 4'd0;
	else
		if(flag == 1)
			if(cnt < 8)
				cnt <= cnt + 4'd1;
			else
				cnt<= 4'd0;
		else
			cnt <= cnt;
end 

always @(*) begin
	if(rst_n == 0)
		wave <= 9'd0;
	else
		case(cnt)
			4'd0	:	wave <= data;
			4'd1	:	wave <= (data*(255 + 32))/255;//1.12倍
			4'd2	:	wave <= (data*(255 + 64))/255;//1.25倍
			4'd3	:	wave <= (data*(255 + 96))/255;//1.37倍
			4'd4	:	wave <= (data*(255 + 128))/255;//1.5倍
			4'd5	:	wave <= (data*(255 + 160))/255;//1.62倍
			4'd6	:	wave <= (data*(255 + 192))/255;//1.75倍
			4'd7	:	wave <= (data*(255 + 224))/255;//1.875倍
			4'd8	:	wave <= (data*(255 + 256))/255;//2倍

			default	:	wave <= 9'd0;
		endcase
end 

endmodule 

        dds_wave模块:顶层模块

module dds_wave(

	input clk,
	input rst_n,
	input key_adjust,//切换波形按键
	input key_freq,//切换频率按键
	input key_ampl,//改变振幅按键
	
	output [8:0] wave
);

	wire flag_adjust;
	wire flag_freq;
	wire flag_ampl;
	wire [31:0] fword;
	wire [7:0] addr;
	wire [9:0] rom_addr;
	wire [7:0] rom_data;

key_top key_top_inst(

			.clk(clk),
			.rst_n(rst_n),
			.key_adjust(key_adjust),
			.key_freq(key_freq),
			.key_ampl(key_ampl),
			
			.flag_adjust(flag_adjust),
			.flag_freq(flag_freq),
			.flag_ampl(flag_ampl)
);

ctrl_freq ctrl_freq_inst(

			.clk(clk),
			.rst_n(rst_n),
			.flag(flag_freq),
			
			.fword(fword)
);

addr_ctrl addr_ctrl_inst(

			.clk(clk),
			.rst_n(rst_n),
			.fword(fword),
			
			.addr(addr)
);

wave_ctrl wave_ctrl_inst(

			.clk(clk),
			.rst_n(rst_n),
			.flag(flag_adjust),
			.addr(addr),
			
			.rom_addr(rom_addr)
);

wave_rom	wave_rom_inst (
	.address ( rom_addr ),
	.clock ( clk ),
	.q ( rom_data )
	);

ampl_ctrl ampl_ctrl_inst(

			.clk(clk),
			.rst_n(rst_n),
			.flag(flag_ampl),
			.data(rom_data),
			
			.wave(wave)
);

endmodule 

        jitter_ctrl模块:状态机进行按键消抖

//三段式
module jitter_ctrl_v2(
 
	input clk,
	input rst_n,
	input key,
	
	output reg flag,
	output reg key_en
);
 
reg [3:0] n_state;
reg [3:0] c_state;
 
parameter s0 = 4'b0001;//空闲状态
parameter s1 = 4'b0010;//下抖动状态
parameter s2 = 4'b0100;//稳定状态
parameter s3 = 4'b1000;//上抖动状态
 
reg [3:0] cnt;
//FSM1
always @(posedge clk,negedge rst_n)
begin
	if(rst_n == 0)
		c_state <= s0;
	else
		c_state <= n_state;
end 
 
//FSM2
always @(*)//描述状态转移
begin
	if(rst_n == 0)
		n_state <= s0;
	else
		case(c_state)
			s0	:	begin
						if(key == 0)//默认按键低电平有效,即=0时按键按下
							n_state <= s1;
						else
							n_state <= s0;
					end 
			s1	:	begin
						if(cnt == 9)//延时计数器判断
							n_state <= s2;
						else
							n_state <= s1;
					end 
			s2	:	begin
						if(key == 1)//按键弹起,状态改变
							n_state <= s3;
						else
							n_state <= s2;
					end 					
			s3	:	begin
						if(cnt == 9)//延时计数器判断
							n_state <= s0;
						else
							n_state <= s3;
					end 		
			default	:	n_state <= s0;
		endcase
end 
 
//FSM3
always @(posedge clk,negedge rst_n)//状态输出产生flag信号
begin
	if(rst_n == 0)
		begin
			cnt <= 4'd0;
			flag <= 1'b0;
			key_en <= 1'b0;
		end
	else
		case(c_state)
			s0	:	begin 
						cnt <= 4'd0;
						flag <= 1'b0;
						key_en <= 1'b0; 
					end 
			s1	:	begin
						if(cnt < 9)//驱动延时计数器
							cnt <= cnt + 4'd1;
						else
							cnt <= 4'd0;
							
						if(cnt == 9)//延时计数器记满,产生flag
							begin
								flag <= 1'b1;//flag只产生一个时钟周期
								key_en <= 1'b1; //输出使能
							end 
						else
							begin
								key_en <= 1'b0; 
								flag <= 1'b0;
							end 
					end 
			s2	:	begin
						flag <= 1'b0;
						key_en <= 1'b1;
						cnt <= 4'd0;
					end 
			s3	:	begin
						flag <= 1'b0;//状态初始化,准备判断下次按键按下
						key_en <= 1'b0;
						if(cnt < 9)
							cnt <= cnt + 4'd1;
						else
							cnt <= 4'd0;
					end 
			default	:	begin
								cnt <= 4'd0;
								flag <= 1'b0;
								key_en <= 1'b0;
							end 
		endcase 	
end 
 
endmodule 

        key_top模块:按键顶层

module key_top(

	input clk,
	input rst_n,
	input key_adjust,
	input key_freq,
	input key_ampl,
	
	output flag_adjust,
	output flag_freq,
	output flag_ampl
);

jitter_ctrl  jitter_ctrl_inst1(

			.clk(clk),
			.rst_n(rst_n),
			.key(key_adjust),
			
			.flag(flag_adjust)
);

jitter_ctrl  jitter_ctrl_inst2(

			.clk(clk),
			.rst_n(rst_n),
			.key(key_freq),
			
			.flag(flag_freq)
);

jitter_ctrl  jitter_ctrl_inst3(

			.clk(clk),
			.rst_n(rst_n),
			.key(key_ampl),
			
			.flag(flag_ampl)
);

endmodule 

        仿真代码

`timescale 1ns/1ps
module dds_wave_tb;

	reg clk;
	reg rst_n;
	reg key_adjust;
	reg key_freq;
	reg key_ampl;
	
	wire [8:0] wave;

dds_wave dds_wave_inst(

			.clk(clk),
			.rst_n(rst_n),
			.key_adjust(key_adjust),//切换波形按键
			.key_freq(key_freq),//切换频率按键
			.key_ampl(key_ampl),//改变振幅按键
			
			.wave(wave)
);

initial clk = 1;
always #10 clk = ~clk;

initial begin
	rst_n = 0;
	key_adjust = 1;
	key_freq = 1;
	key_ampl = 1;
	#200
	rst_n = 1;
	#40000
	key_freq = 0;
	#200
	key_freq = 1;
	#1000
	key_freq = 0;
	#200
	key_freq = 1;
	#1000
	key_freq = 0;
	#200
	key_freq = 1;
	#20000
	key_adjust = 0;
	#200
	key_adjust = 1;
	#20000
	key_adjust = 0;
	#200
	key_adjust = 1;
	#20000
	key_adjust = 0;
	#200
	key_adjust = 1;
	#20000
	key_adjust = 0;
	#200
	key_adjust = 1;
	#20000
	key_ampl = 0;
	#200
	key_ampl = 1;
	#20000
	key_ampl = 0;
	#200
	key_ampl = 1;
	#20000
	key_ampl = 0;
	#200
	key_ampl = 1;
	#20000
	key_ampl = 0;
	#200
	key_ampl = 1;
	#20000
	$stop;
end 

endmodule 

三、仿真验证

运行仿真可以看到波形切换正确,频率切换也是可以的,后面正弦波振幅也是可以控制的

观察数据,初始没有按键操作,此时波形应该是正弦波,50Khz

1/(20000000ps)=50Khz,按下三次频率按键切换后理论上为200Khz

1/(5000000ps) =200Khz,频率切换成功,波形切换成功,下面探究振幅,初始正弦波最值255,,振幅切换按键按下一次后输出最值变为287,为1.12倍,再次按下输出最值变为319,为1.25倍。振幅切换成功。

参考

频率控制字

DDS算法

  • 18
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张明阳.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值