本程序要求设计一个波形发生器,生成正弦波、三角波、经过ASK调制的正弦波和经过BSPK调制的正弦波,通过开关可以选择波形,改变输出频率。各开关的控制功能如表 9 1和表 9 2所示。

表 9 1 波形选择控制

输入端口SW1 SW2波形
wave_selc 0 0ASK调制的正弦波
0 1正弦波
1 0三角波
1 1BPSK调制的正弦波

表 9 2 频率选择控制

输入端口SW3 SW4频率
fre 0 0500KHZ,每周期采样100点
0 11MHZ,每周期采样50点
1 02MHZ,每周期采样25点
1 15MHZ每周期采样10点



图9-1 任意波形发生器原理图

图9-1 任意波形发生器原理图

本实验运用查表法来实现信号发生器,查表法的由相位累加器和存储器构成,如图9 1所示。相位累计器的功能是产生正弦波和三角波的相位值。每隔一个时钟周期,累加器的相位值自动增加一定的相位值,并将当前的相位值作为查找表的输入值进行查表。通过改变每次增加的相位值可以控制输出信号的频率。例如,每个时钟周期累加器的相位值增加90度,则4个时钟周期产生一个完整的正弦波。输出信号的周期为时钟周期的1/4。

查找表用RAM来构造。例如,如果把相位值作为RAM的地址,只要在该地址中存储相应的正余弦幅度值,就可通过相位值寻址RAM,输出正弦函数。

由于FPGA芯片的存储器资源非常有限,如何有效的利用资源成为本实验非常关键的地方。考虑到正弦波以及三角波的周期性与对称性,在RAM表中只需要存储1/2 周期的波形数据即可。在本设计中,一个波形周期内的采样点为100个,因此实际在RAM表中只需存50个采样点,这样就减少了芯片硬件资源的消耗。



3.1 程序架构

程序的总体架构如图9 2所示,程序的顶层模块为arbtywave。其中有四个模块Sinewave、ASKsquwave、BPSKsquwave和triwave,分别生成正弦波、ASK正弦波、BPSK正弦波和三角波。通过一个多路选择器选择需要输出的波形,由输入信号waveselc来控制。 图9-2 程序架构

图9-2 程序架构

顶层模块arbty_wave的输入输出接口如下:

 
input clk;					//系统时钟, 50MHz。
input rst_n;				//异步复位,低电平有效。
input [1:0]wave_selc;		//波形选择开关, sw1, sw2。
input [1:0]fre;				//频率选择开关, sw3, sw4
output [13:0]wave;			//输出波形。
output clk_out;				// D/A转换的时钟

程序中的四个模块发生器的结构非常类似,在此以正弦波为例介绍设计思路。

3.2 sine_wave模块

sine_wave产生频率可调的正弦波形,输入输出接口如下:

 
input clk;				//系统时钟,50MHZ
input clr;				//异步置位,低电平有效
input [1:0]fre;			//频率选择开关
output [13:0]wave_si;   //输出正弦波

本实验要生成的正弦波形图如图9 3所示,过零点在2000H处。在实验原理中已经指出,本实验中采用查表法生成所需要的波形,查找表中存储了正弦波的相位和幅度之间的对应关系,查找表存储在FPGA的内部存储器中,使用QuartusⅡ的Mega Winzard来定制需要的RAM。

每一个周期的正弦波有100个采样点,原则上要在RAM中存储这100个采样点的幅度值,但是由于正弦波的前半个时钟周期和后半个时钟周期是对称的,因此只需要存储前面50个采样点的幅度值即可。后半个时钟周期采样点N的幅度值等于2000H-采样点(N-50)的幅度值。 图9-3  正弦波形图

图9-3 正弦波形图

在生成RAM前,先用matlab计算正弦波的幅度值:

 
          x=round(sin(linspace(0,pi,49))*5200);
          for i=1:1:49
               y=x(i)
          end
y=
0    340  679  1014  1346 1671  1990 2300
2600 2889 3166 3429  3677 3910  4125 4324
4503 4664 4804 4924  5023 5100  5156  5189
5200 5189 5156 5100  5023 4924  4804 4664 
4503 4324 4125 3910  3677 3429  3166 2889
2600 2300 1990 1671  1346 1014  679  340

在Quartus II中新建一个.mif文件,用于存储正弦函数的幅度值,这些值将初始到内部存储器中。在QuartusⅡ中新建.mif文件的过程为:File-〉New-〉Other Files-〉Memory Initialization File。将上述数据复制到.mif文件的表格中(图9 4),保存上述.mif文件为data_sine.mif。 图9-4  mif文件内容

图9-4 mif文件内容

用Quartus II中的Mega Winzard定制一个单端口ROM,具体流程如下:
1) 点击Tools菜单栏下的“Megawizard Plug-in Wizard”选项,新建一个megafunction variation(图 9-5)。 图 9-5 新建megafunction variation

图 9-5 新建megafunction variation

2) 选择ROM:1-PORT,设置器件类型为CycloneⅡ,输出文件类型为Verilog HDL,输入文件名sine,点击下一步(图9-6)。 图9-6 选择RAM类型

图9-6 选择RAM类型

3) 定义存储器深度为50个字(word),存储器的深度为14bit。使用M4K存储器。点击下一步(图9-7)。 图9-7 设置RAM参数

图9-7 设置RAM参数

4) 将新建的data_sine.mif文件导入至RAM中(图9-8)。 图9-8 导入mif文件

图9-8 导入mif文件

5) 然后按finish完成了1-PORT ROM的定制。 在sine_wave模块中,计数器counter作为相位控制器来根据频率的来决定相位的变化。