0%

FPGA函数发生器设计

FPGA函数发生器设计

随着现在工业和科技的不断提高,传统的三极管等分离元件式模拟信号发生器频率稳定性低、可靠性差的特点,已经不可能满足实际应用的需要,所以就必须制作频率稳定性、精确度更高的信号发生器解决这些问题。传统的信号发生器技术对科学的发展带来了很多,而且随着集成电路技术和数字信号处理的发展,直接数字频率合成技术(DDS)已开始被广泛的用于信号发生器的发生和制作当中。

基于现场可编程门阵列器件的高速、高可靠性和现场可编程等优点,本技术已开始广泛应用于数字集成电路设计、数字信号处理、通信等不同的科技领域。利用直接数字频率合成技术FPGA设计的函数信号发生器具有以下优点:

  • 输出相位噪声低;
  • 频率切换速度快;
  • 可以产生任意波形;
  • 全数字化实现,便于集成,体积小,重量轻;
  • 灵活的接口和控制方式;
  • 比专用芯片功耗也低

工程源码

转到github

工作原理

DDS(direct digital synthesizer)是在一组存储器单元中按照信号波形数据点的 输出次序存储了将要输出波形的数据,在控制电路的协调控制下,以一定的速率,周而 复始地将波形数据依次发送给 D/A 转换器转换成相应的模拟信号。由于用硬件电路取代 了计算机的控制,信号输出稳定度高。如需更新输出信号,不必改动任何线路和元器件, 只需改写存储器中的波形数据即可。更主要的是,可以将微处理器从信号输出的负担中解脱出来。工作流程图如下:

基于对函数信号发生器的几种实现方式的了解,本文选择方便调频的直接频率合成 DDS 技术来实现函数信号发生器。 DDS 的核心就是相位累加器,利用它来产生信号递增的相位信息,整个 DDS 系统在 统一的参考时钟下工作,每个时钟周期相位累加器作加法运算一次。加法运算的步进越大,相应合成的相位值变化越快,输出信号的频率也就越高

模块简介

函数发生器分为以下模块:

  • 按键模块:
    通过控制按键,改变频率,相位,占空比。

  • 频率控制模块:
    通过按键模块传来的改变频率的信息,产生相应的频率控制字,传给波形生成模块。

  • 相位控制模块:
    通过按键模块传来的改变相位的信息,产生相应的相位控制字,传给波形生成模块。

  • 三角波模块
    根据时钟信号,生成三角波

  • 正弦波模块
    根据时钟信号,生成正弦波

  • 方波模块
    根据时钟信号,生成方波

  • PWM波模块
    根据时钟信号,生成PWM波

  • 波形控制模块:
    通过波形选择,控制输出信号的波形。

  • 数码管显示模块:
    把频率显示到数码管上。

所有模块如图所示:

仿真效果

错误分析

频率控制字的理解

对频率控制字的理解出现了偏差,最初计划对时钟进行分频来控制波形的频率。根据书上的公式,我们发现可以改变频率控制字来改变输出频率。频率控制字: $f_{out}=\frac{B\left[31..0\right]}{2^{32}}f_{clk} $ 通过改变频率控制字的步进来改变频率步进的大小。

ROM 空间不够

原因:.mif 文件的采样深度太深,数据太多,导致 ROM 空间不够。

按键

  • 按键按下时数码管上显示的频率一直在改变,松开按键时频率回到初值

    我们怀疑是按键未消抖。编写按键消抖,采用了积分延时消抖的方法。

  • 按键消抖后没变化

    成功对按键进行了消抖,但按键按下时数码管上显示的频率一直在改变,松开按键时频率回到初值。我么认为 if else 生成的RTL电路太复杂,尝试改成用case描述。

  • 把 if else 改成了 case,简化了RTL电路

    改成了 case 后,松开按键时频率不会回到初值。但按键按下时数码管上显示的频率仍然一直在改变。经电路分析,我们猜想可能是电路没有触发器的生成,导致在按键按下时,不能做到对按键的下降沿进行检测

如何避免生成锁存器

虽然 always 块里的敏感列表是对下降沿进行检测,但是生成的电路中并没有检测边缘。我们猜测是没有生成触发器的缘故。锁存器最大的危害在于不能过滤毛刺(使能信号有效时,输出状态可能随输入多次变化,产生空翻)。这对于下一级电路是极其危险的。
避免产生锁存器的方法:

  • 给输出变量赋初值
  • 增加的else语句,使得逻辑完备。
  • 时序逻辑电路不会产生锁存器

我们进行了上述操作,成功避免生成了锁存器,但是仍然不能生成触发器。通过网上查找资料,我们发现网上的写法普遍是检测按键后由程序生成一个下降沿,在always块里对该下降沿进行检测。

把按键电平转换为脉冲

  • 使用一个模块,在模块内记录按键的上一个电平的情况,与本次电平进行逻辑操作:assign buttonout=~((key_temp)&&(!buttonin));该操作使得仅在按键按下的时候有一个脉冲。

  • 由于assign buttonout仅是一个单脉冲,顾FPGA可能会将该脉冲视为噪声,故需要电平优化:

1
2
wire [2:0]PushButton/* synthesis keep="1" */;
wire [2:0]PushButtonafter/* synthesis keep="1" */;

电平优化后,按键基本正常

心得体会

在两周之前,我们虽然学过EDA这门课、知道Quartus ii、学过Verilog HDL,可是基本不会用,通过两周的课程设计,我们可以进行编程设计,收获颇丰。实践是检验真理的唯一标准,我们这次设计的内容就是在Quartus ii环境中,利用Verilog HDL 语言设计出函数发生器,还要与硬件相结合,把程序加载到芯片上,观察真正的效果。所以,在整个设计学习过程中,我们对EDA这门课有了更深层次的了解,在编写程序的过程中也加深了对Verilog HDL 语言的了解及运用能力。在设计过程中,困难重重,从开始的茫然,到后来的渐渐熟悉,再到最后的设计成型,我们都在一直努力解决问题,一个模块一个模块的考虑再到最后把它们整合在一起,最终完成了这次设计。

为期两周的FPGA课程设计已经结束,从挑选课设题目,查阅资料,到研究出总体设计,详细设计,再到最后的编程上机调试,修改程序,完善程序,收获颇多。锻炼了自己独立发现问题、分析问题和通过查看相关资料来解决问题的能力,使自己扩大了知识面,提高了知识水平。借助仿真软件,不仅可以把课堂中所学到的知识,直接加以运用,而且还可以把各个分离的知识组合为一个整体,真正做到理论联系实际的重要性,使自己在专业知识和动手能力上有了很大的提高。


EOF