资源描述
课程设计
基于FPGA和Quartus II设计的智能函数发生器
题 目 基于FPGA和Quartus II设计的智能函数发生器
所在院(系) 物理与电信工程学院
基于FPGA和Quartus II设计的智能函数发生器
[摘要] 信号发生器又称信号源或振荡器,在生产实践和科技领域中有着广泛的应用。它能够产生多种波形,如三角波、锯齿波、矩形波(含方波)、正弦波等,在电路实验和设备检测中具有十分广泛的用途。例如在通信、广播、电视系统中,都需要射频(高频)发射,这里的射频波就是载波,把音频(低频)、视频信号或脉冲信号运载出去,就需要能够产生高频的振荡器。在工业、农业、生物医学等领域内,如高频感应加热、熔炼、淬火、超声诊断、核磁共振成像等,都需要功率或大或小、频率或高或低的信号发生器。本设计采用FPGA来设计制作多功能信号发生器。该信号发生器可以产生锯齿波、三角波、方波等波形。
[关键词] 信号发生器;VHDL;FPGA;三角波;方波;锯齿波。
目录
1.引言 1
2.FPGA简介 1
2.1 VHDL 和 Verilog简介 3
2.2 设计工具简介 3
3.系统设计 3
3.1 VHDL程序语言基本设计 3
3.2波形发生器设计 4
3.3 程序设计原理框图 4
4 系统的软件设计与仿真 6
4.1 系统仿真时序图 6
4.2 RTL仿真硬件图 7
5总结体会与展望 8
参考文献 9
附录A 设计原理图 10
附录B 系统仿真图 11
附录C 源程序清单 13
1.引言
20世纪90年代,国际上电子和计算机技术较先进的国家,一直在积极探索新的电子电路设计方法。电子设计自动化(EDA)工具给电子设计带来了巨大的变革,特别是可编程逻辑器件和硬件描述语言的出现和发展,解决了用传统的方法设计较大系统工程时的诸多不便,成为电子电路设计人员最得力的助手。随着计算机和EDA技术的发展,基于FPGA的电子设计则是目前发展较为迅速的一个领域,而且广泛应用于计算机、通信等各个领域。因此,本文主要利用VHDL,设计制作一个多功能波形发生器。采用传统的模拟振荡电路构成的波形发生器产生的信号频率精度低,不仅成本高,外围电路复杂,易受外界干扰,而且调试困难,不便于调控,实现的性能指标也不理想。对此采用具有良好性能的专用集成芯片就能达到本题的目的要求。但采用该方法所需的外围电路模块多且较为复杂,不利于控制和问题的检查。而纯单片机的方法虽便于控制但又难以达到题目的要求。
现如今是信息时代,人们对使用计算机获取信息、处理信息的依赖性也越来越高。因此,利用FPGA采用DDS的方式来设计的波形发生器前景十分可观。
随着电子技术的飞速发展,VHDL作为标准化的硬件描述语言获得了广泛的应用。无论是采用传统的模拟振荡电路还是专用的集成芯片所作的波形发生器已不能满足需要。因此,对波形发生器的设计势在必行。本文主要利用VHDL语言,设计制作一个多功能波形发生器,能实现多种波形的输出及组合,并进行仿真。
2.FPGA简介
FPGA(Field-Programmable Gate Array)即现场可编程门阵列,它是在PAL、GAL、CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的不足,又克服了原有可编程器件门电路数有限的缺点。
与传统们阵列和掩模可编程门阵列(MPGA)相比,FPGA具有很多的优点,传统门阵列可以用来设计任何电路,但是只能在工厂中一次性编程,而且还需要针对该电路的特定的掩模。FPGA是标准通用器件。使用其代替MPGA,可以将设计时间由几个月缩短至几小时,并且使设计更加简单,从而减少了错误修改和设计指标变更的花费。
FPGA器件在结构上,由逻辑功能块排列为阵列,它的结构可以分为三个部分:可编程快CLB(Configurable Logic Blocks)、可编程I/O模块IOB(Input Block)和可编程内部连线PI(Programmable Interconnect)。CLB在器件中排列为阵列,周围有环形内部连线,IOB分布在四周的管脚上。
FPGA也存在缺点,FPGA中,每个可编程的点都有电阻和电容。电阻和电容的使用减慢了信号的传输速度,所以FPGA的速度比传统门阵列要低,而且,FPGA中互联延迟是不可预测的。
FPGA的基本特点主要有:
一、采用FPGA设计ASIC电路,用户不需要投片生产,就能得到合用的芯片。
二、FPGA可做其它全定制或半定制ASIC电路的中试样片。
三、FPGA内部有丰富的触发器和I/O引脚。
四、FPGA是ASIC电路中设计周期最短、开发费用最低、风险最小的器件之一。
五、FPGA采用高速CHMOS工艺,功耗低,可以与CMOS、TTL电平兼容。
使用FPGA时,可以根据不同的配置模式,采用不同的编程方式。加电时,FPGA芯片将EPROM中数据读入片内编程RAM中,配置完成后,FPGA进入工作状态。掉电后,FPGA恢复成白片,内部逻辑关系消失,因此,FPGA能够反复使用。FPGA的编程无须专用的FPGA编程器,只须用通用的EPROM、PROM编程器即可。当需要修改FPGA功能时,只需换一片EPROM即可。这样,同一片FPGA,不同的编程数据,可以产生不同的电路功能。因此,FPGA的使用非常灵活。FPGA有多种配置模式:并行主模式为一片FPGA加一片EPROM的方式;主从模式可以支持一片PROM编程多片FPGA;串行模式可以采用串行PROM编程FPGA;外设模式可以将FPGA作为微处理器的外设,由微处理器对其编程。
2.1 VHDL&Verilog简介
VHDL(Very High Speed Integrated Circuit Hardware Description Language,超高速集成电路硬件描述语言)是一种用来描述数字系统行为和结构的硬件描述语言,被广泛的运用于描述和仿真各种数字系统,小到几个门,大到许多复杂集成电路相连的系统。
VHDL诞生于1982年,是由美国国防部开发的一种快速设计电路的工具,目前已经成为IEEE(The Institute of Electrical and Electronics Engineers)的一种工业标准硬件描述语言。相比传统的电路系统的设计方法,VHDL具有多层次描述系统硬件功能的能力,支持自顶向下(Top to Down)和基于库(Library Based)的设计的特点,因此设计者可以不必了解硬件结构。从系统设计入手,在顶层进行系统方框图的划分和结构设计,在方框图一级用VHDL对电路的行为进行描述,并进行仿真和纠错,然后在系统一级进行验证,最后再用逻辑综合优化工具生成具体的门级逻辑电路的网表,下载到具体的FPGA器件中去,从而实现可编程的专用集成电路(ASIC)的设计。
Verilog也是一种流行的硬件描述语言,他是由工业界开发的,1984年,Verilog作为一种私用的硬件描述语言,由Gateway Design Automation公司给出,1988年,Synopsis公司为Verilog开发了综合工具。1995年,Verilog成为IEEE的一个标准。Verilog 适合算法级,寄存器级,逻辑级,门级和版图级等各个层次的设计和描述。
VHDL的语法是基于ADA语言的,而Verilog的语法是基于C语言的。由于是基于C语言,所以它更容易掌握,但是VHDL语言在设计和描述大型系统时具有突出优势。目前两种语言各占一半市场份额,两种语言都可以满足数字系统设计者的需求。
本设计中采用VHDL语言进行设计。
2.2 设计工具简介
本次设计是基于Altera公司的QuartusII软件。
Quartus II 是Altera公司的综合性PLD开发软件,支持原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。
QuartusII支持Altera的IP核,包含了LPM/MegaFuction宏功能模块库,使用它,可以简化设计的复杂性,加快设计速度。QuartusII平台支持一个工作组环境下的设计要求,其中包括支持基于Internet的协作设计。此外,QuartusII通过和DSP Builder工具与Matlab/SIMULINK相结合,可以方便地实现各种DSP应用系统;支持Altera的片上可编程系统开发,集系统级设计、嵌入式软件设计、可编程逻辑设计于一体,是一种综性的开发平台。
3 系统设计
3.1 VHDL程序语言基本设计
一个VHDL语言的设计程序描述的是一个电路单元,这个电路单元可以是一个门电路,或者是一个计数器,也可以是一个CPU,一般情况下,一个完整的VHDL语言程序至少包括实体、结构体和程序包三个部分。实体给出电路单元的外部输入输出接口信号和引用信息,结构体给出了电路单元的内部结构和信号的行为特点,程序包定义在设计结构体和实体中将用到的常数、数据类型、子程序和设计好的电路单元等。
第一部分是程序包,程序包是用VHDL语言编写的共享文件,定义在设计结构体和实体中将要用到的常数、数据类型、子程序和设计好的电路单元等,放在文件目录名称为IEEE的程序包库中。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
第二部分是程序的实体,定义电路单元的输入/输出引脚名称。程序的实体名称可以任意取,但必须与VHDL程序的文件名称相同。实体的标示符是ENTITY,实体以ENTITY开头,以END结束。
ENTITY fulladder IS
PORT(a,b,Ci:in std_logic;
Co,s: out std_logic_vector(7 downto 0));
END fulladder;
其中,定义了a,b, Ci为输入信号引脚,定义Co,s为输出信号引脚。
第三部分是程序的结构体,具体描述电路的内部结构和逻辑功能。结构体有三种描述方式,分别是行为(BEHAVIOR)描述方式、数据流(DATAFLOW)描述方式和结构描述方式。其中数据流描述方式又被称为寄存器(RTL)描述方式。结构体以表示ARCHITECHTURE开头,以END结尾。结构体的名称可以任取。
architecture behav of fulladder is
BEGIN
s<=a xor b xor Ci;
Co<=(a and b)or(a and Ci)or(b and Ci);
END fulladder
上面程序段中结构体的描述方式属于程序流描述方式。
以上三段程序是一个完整的VHDL程序段,实现的功能是一位全加器。
3.2波形设计
采用DDS技术可以很方便地产生各种高质量的波形。DDS技术是从相位概念出发之结合成所需要波形的一种频率合成技术。以正弦波为例,首先要按照一定的采样点数将正弦波形一个周期的数据信息存于ROM表中,表中包含着一个周期正弦波的数字幅度信息,每个地址对应正弦波中0到360度范围内的一个相位点的幅度值,查找表时即是把输入的地址相位信息映射成正弦波幅度的数字量信号,通过设置的输出端口输出。在实物设计中,可以使用D/A接口来实现波形信号的输出。
为简化设计过程,本设计并未采用DDS技术,而是采用描点输出的方式,实现波形发生器的设计。程序中设置一个波形的起始点,经过比较、计算得出波形的其他数值,将这些点依次连续输出,从而实现波形的仿真。以递增锯齿波为例,首先定义初始点为 tmp=“00000000”;在时钟上升沿到来时,执行tmp<=tmp+1;语句,同时将tmp输出,当
tmp=“11111111”;时,将tmp值清零,执行下一个循环。
在本设计中,采用QuartusII软件仿真,所以可以通过波形文件直观的反映出输出的数字量的变化情况,以达到波形输出的仿真。
3.3 程序设计原理框图
参考频率源
相位累加器
波形存储器
数模转换器
频率控制字
4 系统的软件设计与仿真
4.1 系统仿真时序图
4.2 仿真软件Proteus简介
Proteus软件是英国Labcenter electronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前最好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC、AVR、ARM、8086和MSP430等,2010年即将增加Cortex和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器,系统仿真图如下图所示:
4.1 RTL仿真硬件图
RTL原理图RTL Viewer
4.2 Technolog Map View
Technology Map View
5总结体会与展望
不停的查找相关资料使我更深入地学习了相关专业知识,并能够熟练的操作QuartusⅡ软件。通过对FPGA芯片的使用及对VHDL硬件描述语言学习,让我感到了VHDL硬件描述语言的方便性和灵活性,可以使编程技能快速提高。
设计以FPGA为核心,详细阐述了FPGA内部实现的功能及VHDL程序设计仿真。单片机的设计仅属于本设计的辅助控制部分,且单片机的资料很多,所以在此对单片机的程序不作详细说明。设计采用直接数字频率合成技术设计了双通道相位关系可调的信号发生器,输出信号频率范围为0~20KHz,频率分辨率高于20Hz,相位调节步进1°。两个通道不仅可以输出相同频率的信号,还可以输出不同相位、不同幅值的正弦信号。经系统仿真表明,本设计可达到预定要求。
在实际的操作测试中发现用case语句取代了定义ROM造成了数据开始并没有固化在ROM中而是从程序中写入再读出。反复的查找资料找到解决办法是用function语句对ROM进行定义并装初值
。而且类似的实际问题还有很多,比如应该注意传递函数中的输出端口应该是wire型的,如果定义为reg将会出错;开始时波形数据按照图放入初值时,有负数、小数等,当装入负数小数后在仿真中无法正确显示数字。(解决办法:将波形平移扩大将小数和负数换算成整数装入即可显示波形数据)
;关键的问题是怎样实现寻址的操作,首先是定义一个从0—7的循环加法计数器作为段内基地址寻址,然后通过case语句choose波形选择相应波段的段地址等。
这次课程设计养成了去图书馆查阅书籍和上网搜集资料的良好习惯,提高了自己独立分析和解决实际问题的能力,还锻炼了我们的团队合作的能力。坚定地进入实验室,为我的兴趣所向而努力。这为我们以后的毕业设计奠定了良好的基础,并更好地复习和巩固了以前学过的理论知识。但在信息技术飞速发展的今天,各种电子产品层出不穷,各种技术与方法也在不断地改善,因此对电子技术知识的学习也应不断地充实和更新,以适应工作与社会的需要。
这样的实验结合学习和工作应用,通过自己动手更加能够充分掌握所学知识,将书本和实际结合起来。同时也认识到EDA技术是当前数字系统设计领域比较通用的一种工具,它可以大大缩短设计需要的时间,降低成本的同时也提高了系统的稳定性。使用VHDL语言描述硬件系统使得EDA技术有了更为广阔的空间。简易波形发生器在生活中各个场合都有着大量的使用术。EDA技术比我们想象中的要有很大的难度,里面有很多的思想来源于信息电子技术辑算法的设计,需要有很强的C语言编程功底。学习一门知识要从最基本的体系构架开始,倘若一开始就从顶层设计入手,就会造成很多基本原理、基本概念上的偏差,里面的基本知识还包括电路的概念以及寄存器传送的基本知识。书越读越觉得自己会的越少,我虽然快大学本科毕业,但我深刻的认识到自己还仅仅处于电子这个庞大学科的初级入门阶段,还有更多的知识需要我慢慢去学习和探索。总之,本次课程设计给即将走向工作岗位的我带来了很大的帮助及深远的影响。
参考文献
[1] 蒋小燕,俞伟钧.EDA技术及VHDL.南京:东南大学出版社.2008年12月.
[2] 李国丽,朱维勇.EDA与数字系统设计.北京:机械工业出版.2005年3月.
[3] 江国强.EDA技术与实验.北京:电子工业出版社.2005年1月.
[4] 欧伟明.基于MCU、FPGA、RTOS的电子系统设计方法与实例.北京:北京航空航天大学出版社.2007年4月 .
[5] Charles H.Roth,Jr、Lizy Kurian John著,金明录译.数字系统设计与VHDL.北京:电子工业出版社.2008年8月
附录A设计原理图
智能信号发生器原理设计框图
附录B系统仿真图
图1.波形时序仿真图
图2.正弦波RTL原理图
图3.文件顶层程序
附录C源程序清单
/***************************************************
名称:基于FPGA和Quartus II的智能函数发生器设计程序(VHDL编程)
***************************************************/
--*****************
--顶层文件
--****************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity boxin is
port (
clk,reset: in std_logic;
sel: in std_logic_vector(1 downto 0);
q:out std_logic_vector(7 downto 0));
end entity;
architecture boxin_arc of boxin is
component zeng is--元件模块调用
port (
clk,reset: in std_logic;
q0: out std_logic_vector(7 downto 0));
end component;
component jian is--元件调用
port (
clk,reset: in std_logic;
q1: out std_logic_vector(7 downto 0));
end component;
component sanjiao is--元件调用
port (
clk,reset: in std_logic;
q2: out std_logic_vector(7 downto 0));
end component;
component fangbo is--元件调用
port (
clk,clr: in std_logic;
q3: out std_logic_vector(7 downto 0));
end component;
component xuan_4 is--元件调用
port (
sel: in std_logic_vector(1 downto 0);
d0,d1,d2,d3: in std_logic_vector(7 downto 0);
q:out std_logic_vector(7 downto 0) );
end component;
signal y0,y1,y2,y3:std_logic_vector(7 downto 0);
begin
u0: zeng port map(clk=>clk,reset=>reset,q0=>y0);
u1: jian port map(clk=>clk,reset=>reset,q1=>y1);
u2: sanjiao port map(clk=>clk,reset=>reset,q2=>y2);
u3: fangbo port map(clk=>clk,clr=>reset,q3=>y3);
u4: xuan_4 port map(sel=>sel,d0=>y0,d1=>y1,d2=>y2,d3=>y3,q=>q);
end boxin_arc;
--************************
--****递增锯齿波的设计程序****—
--************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity zeng is
port
(
clk,reset: in std_logic;
q0: out std_logic_vector(7 downto 0)
);
end entity;
architecture zeng_arc of zeng is
signal m0:integer range 0 to 7;
signal tmp0:std_logic_vector(7 downto 0);
begin
process(clk,reset)--敏感信号
begin
if reset='0' then
m0<=0;
elsif clk'event and clk='1' then
if m0=7 then m0<=0;--定义8分频,实际时增大数字,减小分频系数,因为FPGA系统的时钟为50MH的。
if tmp0="11111111" then tmp0<="00000000";--产生锯齿波
else tmp0<=tmp0+1;--递增
end if;
else m0<=m0+1;
end if;
end if;
q0<=tmp0;
end process;
end zeng_arc;
--***************
--递减锯齿波的产生
--**************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity jian is
port
(
clk,reset: in std_logic;
q1: out std_logic_vector(7 downto 0)
);
end entity;
architecture jian_arc of jian is
signal m1:integer range 7 to 0;
signal tmp1:std_logic_vector(7 downto 0);
begin
process(clk,reset)--敏感信号
begin
if reset='0' then
m1<=7;
elsif clk'event and clk='1' then
if m1=0 then m1<=7;--定义8分频,实际时增大数字,减小分频系数,因为FPGA系统的时钟为50MH的。
if tmp1="00000000" then tmp1<="11111111";--产生锯齿波
else tmp1<=tmp1-1;--递减
end if;
else m1<=m1-1;
end if;
end if;
q1<=tmp1;
end process;
end jian_arc;
--****************
--*******三角波****
--*****************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity sanjiao is
port (
clk,reset: in std_logic;
q2: out std_logic_vector(7 downto 0));
end entity;
architecture sanjiao_arc of sanjiao is
signal m2:integer range 0 to 7;
signal tmp2:std_logic_vector(7 downto 0);
begin
process(clk,reset)--敏感信号
variable a: std_logic:='0';
begin
if reset='0' then
m2<=0;
elsif clk'event and clk='1' then
if m2=7 then m2<=0;--定义8分频,实际时增大数字,减小分频系数,因为FPGA系统的时钟为50MH的。
if a='0' then
if tmp2="11111110" then
tmp2<="11111111";--向上的锯齿波
a:='1';
else tmp2<=tmp2+1;
end if;
else
if tmp2="00000001" then--向下锯齿波
tmp2<="00000000";
a:='0';
else
tmp2<=tmp2-1;
end if;
end if;
else m2<=m2+1;--分频自加
end if;--分频if结束
end if;--复位信号if结束
q2<=tmp2;
end process;
end sanjiao_arc;
--************
--****方波****
--************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fangbo is
port(
clk,clr: in std_logic;
q3: out std_logic_vector(7 downto 0));
end entity;
architecture fangbo_arc of fangbo is
signal t: bit;
begin
process(clk,clr)--敏感信号
variable cnt: integer range 0 to 63;
begin
if clr='0' then
t<='0';
elsif clk'event and clk='1' then
if cnt<63 then cnt:=cnt+1;--定义64分频,实际时增大数字,减小分频系数,因为FPGA系统的时钟为50MH的。
else
cnt:=0;
t<=not t;
end if;
end if;
end process;
process(clk,t)
begin
if clk'event and clk='1' then
if t='1' then
q3<="11111111";
else
q3<="00000000";
end if;
end if;
end process;
end fangbo_arc;
--****************
--波形选择,通过sel信号选择不同的波形
--****************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity xuan_4 is
port (
sel: in std_logic_vector(1 downto 0);
d0,d1,d2,d3: in std_logic_vector(7 downto 0);
q:out std_logic_vector(7 downto 0) );
end entity;
architecture xuan_4_arc of xuan_4 is
begin
process(sel)
begin
case sel is
when "00"=>q<=d0;
when "01"=>q<=d1;
when "10"=>q<=d2;
when "11"=>q<=d3;
when others=>null;
end case;
end process;
end xuan_4_arc;
/***************************************************
名称:基于Verilog编程的智能函数发生器设计程序
***************************************************/
module Sin(f_clk,p,choose,data);//端口设定
input [5:0] p; //频率控制字
input[1:0] choose; //波形选择
input f_clk; //内置晶振
output [7:0] data;
wire [7:0]data;
reg [5:0] addr,address;
reg [5:0] i;
reg f_out;
initial
begin
i<=0;
addr<=0;
f_out<=0;
end
always @(posedge f_clk) //利用计数器实现任意分频
begin
if(i==p) //设定频率控制字p
begin
i=0;
f_out=~f_out;
end
else
i=i+1;
end
function [7:0] romout; //ROM的设定
input[5:0] address;
case(address) //各波形初值的预装入
0 : romout = 10; //正弦波初值
1 : romout = 17;
2 : romout = 15;
3 : romout = 17;
4 : romout = 10;
5 : romout = 3;
6 : romout = 5;
7 : romout = 3;
8 : romout = 3; //方波初值
9 : romout = 3;
10: romout = 3;
11: romout = 3;
12: romout = 1;
13: romout = 1;
14: romout = 1;
15: romout = 1;
16 : romout = 0; //正三角波初值
17 : romout = 5;
18 : romout = 10;
19 : romout = 15;
20 : romout = 20;
21 : romout = 25;
22 : romout = 30;
23 : romout = 35;
24 : romout = 35; //反三角波初值
25 : romout = 30;
26 : romout = 25;
27 : romout = 20;
28 : romout = 15;
29 : romout = 10;
30 : romout = 5;
31 : romout = 0;
default : romout = 10'hxx;
endcase
endfunction
always@(posedge f_out)
begin
if(addr==8) //波形数据切换
addr=0;
else
展开阅读全文