资源描述
函数信号发生器
摘要:函数信号发生器在生产实践和科技领域有着广泛的应用。本设计是采用了EDA技术设计的函数信号发生器。此函数信号发生器的实现是基于VHDL语言描述各个波形产生模块,然后在QuartusⅡ软件上实现波形的编译。整个系统由波形产生模块和波形选择模块两个部分组成。最后经过QuartusⅡ软件仿真,证明此次设计可以输出正弦波、方波、三角波,锯齿波,阶梯波等规定波形,并能根据波形选择模块的设定来选择波形输出。
关键字:函数信号发生器;VHDL;QuartusⅡ
题目分析:
要求设计一个函数发生器,该函数发生器能够产生递增斜波、递减斜波、方波、三角波、正弦波、及阶梯波,并且可以通过选择开关选择相应的波形输出;系统具有复位的功能;通过按键确定输出的波形及确定是否输出波形。FPGA是整个系统的核心,构成系统控制器,波形数据生成器,加法器,运算/译码等功能。
通过以上分析设计要求完成的功能,确定函数发生器可由递增斜波产生模块、递减斜波产生模块、三角波产生模块、阶梯波产生模块、正弦波产生模块、方波产生模块和输出波形选择模块组成,以及按键复位控制和时钟输入。由此可确定系统的总体原理框图为:
波形发生模块
时钟
clk
复位
reset
波形输出选择模块
图1 系统总体原理框图
方案选择
1、波形函数发生方案对比选择
波形函数发生是本设计的最重要的部分,实现函数发生的途径也有很多,因此必须选择一种易于实现且精度高的方案,以此来提高本设计的实用性。
方案一:通过单片机控制D/A,输出三种波形。此方案输出的波形不够稳定,抗干扰能力弱,不易调节,而且达不到题目要求的六种波形。
方案二:使用传统的锁相频率合成方法。通过芯片IC145152,压控振荡器搭接的锁相环电路输出稳定性极好的正弦波,再利用过零比较器转换成方波,积分电路转换成三角波。此方案,电路复杂,干扰因素多,不易实现。
方案三:利用MAX038芯片组成的电路输出波形。MAX038是精密高频波形产生电路,能够产生准确的三角波、方波和正弦波三种周期性波形,但无法实现阶梯波和递增递减斜波的产生。
方案四:利用在系统编程技术和FPGA芯片产生。用VHDL语言编写程序,调试成功后下载至实验装置的芯片上,再利用外接D/A转换电路实现以上设计功能。此种方案完全可以生成设计要求的6种波形,而且通过软件仿真可以直观的观测的输出的波形参数,方便调试和更改波形参数,外围电路简单,减少器件损耗,精度高。
基于方案四的外围电路简单容易实现、波形产生精度高、易于仿真观测调试的优点,因此本设计的函数发生器选择方案四完成波形发生的全部功能。
2、波形函数输出控制方式选择
方案一:控制多路D/A开关输出方式
此种方案为每一路输出的波形函数使用一路D/A转换后输出,通过控制开关控制每一路D/A是否工作,决定输出的波形。此种方案可以同时输出多路波形,但是需要路D/A转化器,外围电路复杂,制作成本较高而且控制复杂。
方案二:采用数据选择器方式
此种方案可以利用VHDL语言写出数据选择器,然后每种函数发生器的输出和数据选择器输入相连接,通过控制开关选择对应的波形输出。方案二完全可以得到方案一的设计要求,而且只需一个D/A转换器就可以。电路不需要外部搭建,节约成本且控制简单方便。在实验课时候已经完成8选1数据选择器的设计制作,因此本次设计可以直接调用。
方案三:采用数据分配器方式
此种方案利用数据分配器的功能,通过控制开关选择相应的函数发生器模块,使之产生相应的波形输出,并通过数据分配器的使能复位控制决定是否输出波形,此种方案和方案二很相似,也能够实现设计的功能也具有方案二的优点,。
基于方案二的设计简便、节约制作元件和成本、控制简便等优点,选择方案二作为波形函数输出控制方式。
系统细化框图
系统时钟输入后,通过复位开关选择是否产生波形,当各个模块产生相应的信号波形后,通过波形选择模块波形选择开关选泽输出不同的波形,再通过D/A转换器转换,就可以把数字信号(由FPGA输出)变成了相应模拟的信号波形。整个系统设计的核心就是FPGA部分。
波形选择模块
递增斜波模块
递减斜波模块
三角波模块
阶梯波模块
正弦波模块
方波模块
时钟
clk
复位
reset
波形选择开关
D/A转换器
图2系统细化框图
各模块程序设计及仿真
1、递增斜波模块
a) 递增斜波信号产生模块元件图:
图3 递增斜波元件图
b) 代码:
LIBRARY IEEE;--斜波递增
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ICRS IS
PORT (clk,reset:in std_logic;
q:out std_logic_vector(7 downto 0));
END;
ARCHITECTURE behave OF ICRS IS
BEGIN
PROCESS(clk,reset)
VARIABLE tmp: std_logic_vector(7 downto 0);
BEGIN
IF reset='0' THEN
tmp:="00000000";
ELSIF clk' event and clk='1' THEN
IF tmp="11111111" THEN
tmp:="00000000";
ELSE tmp:=tmp+1;
END IF;
END IF;
q<=tmp;
END PROCESS;
END;
c) 递增斜波仿真波形:
图4 递增斜波仿真波形
2、递减斜波模块
a) 递减斜波信号产生模块元件图:
图5 递减斜波元件图
b) 代码:
LIBRARY IEEE;--斜波递减
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY DCRS IS
PORT ( clk,reset:in std_logic;
q:out std_logic_vector(7 downto 0));
END;
ARCHITECTURE behave OF DCRS IS
BEGIN
PROCESS(clk,reset)
VARIABLE tmp: std_logic_vector(7 downto 0);
BEGIN
IF reset='0' THEN
tmp:="11111111";
ELSIF clk'event and clk='1' THEN
IF tmp="00000000" THEN
tmp:="11111111";
ELSE
tmp:=tmp-1;
END IF;
END IF;
q<=tmp;
END PROCESS;
END;
c) 递减斜波仿真波形:
图6递减斜波仿真波形
3、三角波模块
a) 三角波信号产生模块元件图:
图7 三角波元件图
b) 代码:
library ieee; --三角波
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity DELTA is
port(reset:in std_logic;
clk:in std_logic;
q:out std_logic_vector(7 downto 0));
end;
architecture behave of DELTA is
begin
process(clk,reset)
variable tmp:std_logic_vector(7 downto 0);
variable a:std_logic;
begin
if reset='0' then q<="00000000";
else if clk'event and clk='1' then
if a='0' then
if tmp="11111110" then
tmp:="11111111";
a:='1';
else tmp:=tmp+1;
end if;
else
if tmp="00000001" then
tmp:="00000000";
a:='0';
else tmp:=tmp-1;
end if;
end if;
end if;
q<=tmp;
end process;
end;
c) 三角波仿真波形:
图8 三角波仿真波形
4、阶梯波模块
a) 阶梯波信号产生模块元件图:
图9 阶梯波元件图
b) 代码:
library ieee;--阶梯波
use ieee.std_logic_1164.all;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY LADDER IS
PORT (clk,reset:in std_logic;
q:out std_logic_vector(7 downto 0));
END;
ARCHITECTURE behave OF LADDER IS
BEGIN
PROCESS(clk,reset)
VARIABLE tmp: std_logic_vector(7 downto 0);
BEGIN
IF reset='0' THEN
tmp:="00000000";
ELSIF clk 'event and clk='1' THEN
IF tmp="11111111" THEN
tmp:="00000000";
ELSE
tmp:=tmp+16;
END IF;
END IF;
q<=tmp;
END PROCESS;
END;
c) 阶梯波仿真波形:
图10 阶梯波仿真波形
5、正弦波模块
a) 正弦波信号产生模块元件图:
图11 正弦波元件图
b) 代码:
library ieee; --正弦波
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity sin_rom is
port(clk,clr:in std_logic;
d:out integer range 0 to 255);
end;
architecture behave of sin_rom is
begin
process(clk,clr)
variable tmp:integer range 0 to 63;
begin
if clr='0' then
d<=0;
elsif clk'event and clk='1' then
if tmp=63 then
tmp:=0;
else
tmp:=tmp+1;
end if;
case tmp is
when 00=>d<=255; when 01=>d<=254; when 02=>d<=252;
when 03=>d<=249; when 04=>d<=245; when 05=>d<=239;
when 06=>d<=233; when 07=>d<=225; when 08=>d<=217;
when 09=>d<=207; when 10=>d<=197; when 11=>d<=186;
when 12=>d<=174; when 13=>d<=162; when 14=>d<=150;
when 15=>d<=137; when 16=>d<=124; when 17=>d<=112;
when 18=>d<=99; when 19=>d<=87; when 20=>d<=75;
when 21=>d<=64; when 22=>d<=53; when 23=>d<=43;
when 24=>d<=34; when 25=>d<=26; when 26=>d<=19;
when 27=>d<=13; when 28=>d<=8; when 29=>d<=4;
when 30=>d<=1; when 31=>d<=0; when 32=>d<=0;
when 33=>d<=1; when 34=>d<=4; when 35=>d<=8;
when 36=>d<=13; when 37=>d<=19; when 38=>d<=26;
when 39=>d<=34; when 40=>d<=43; when 41=>d<=53;
when 42=>d<=64; when 43=>d<=75; when 44=>d<=87;
when 45=>d<=99; when 46=>d<=112; when 47=>d<=124;
when 48=>d<=137; when 49=>d<=150; when 50=>d<=162;
when 51=>d<=174; when 52=>d<=186; when 53=>d<=197;
when 54=>d<=207; when 55=>d<=217; when 56=>d<=225;
when 57=>d<=233; when 58=>d<=239; when 59=>d<=245;
when 60=>d<=249; when 61=>d<=252; when 62=>d<=254;
when 63=>d<=255; when others=>null;
end case;
end if;
end process;
end;
c) 正弦波仿真波形:
图12 正弦波仿真波形
6、方波模块
a) 代码:
library ieee; --方波
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fangbo is
port(clk,reset:in std_logic;
q:out std_logic_vector(7 downto 0));
end;
architecture behave of fangbo is
signal a:std_logic;
begin
process(clk,reset)
variable tmp:std_logic_vector(7 downto 0);
begin
if reset='0' then
a<='0';
elsif clk'event and clk='1' then
if tmp="11111111" then
tmp:="00000000";
else
tmp:=tmp+1;
end if;
if tmp<="10000000" then
a<='1';
else
a<='0';
end if;
end if;
end process;
process(clk,a) --信号输出
begin
if clk'event and clk='1' then
if a='1' then
q<="11111111";
else
q<="00000000";
end if;
end if;
end process;
end;
b) 方波仿真波形:
图14 方波仿真波形
7、输出波形选择模块
a) 选择器信号产生模块元件图:
图15 选择器元件图
b) 代码:
LIBRARY IEEE;--选择器
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY Xuanzeqi IS
PORT ( sel: in std_logic_vector(2 downto 0);
d1,d2,d3,d4,d5,d6:in std_logic_vector(7 downto 0);
q:out std_logic_vector(7 downto 0));
END;
ARCHITECTURE behave OF Xuanzeqi is
BEGIN
PROCESS(sel)
BEGIN
CASE sel IS
WHEN "001"=>q<=d1;--锯齿波递增
WHEN "010"=>q<=d2; --锯齿波递减
WHEN "011"=>q<=d3; --三角波
WHEN "100"=>q<=d4; --阶梯波
WHEN "101"=>q<=d5; --方波
WHEN "110"=>q<=d6; --正弦波
WHEN OTHERS=>null;
END CASE;
END PROCESS;
END;
c) 选择器仿真波形:
图16 选择器波形图
系统联调测试分析
通过以上各个模块的细化和分析,最终在Quartus ‖中完成了整个系统的联合调试,并通过嵌入式逻辑分析的方法回读输出信号的波形符合设计的要求。调试整个系统了原理图如下图所示:
调试的结果如下:(复位信号reset高电平,低电平为不输出)
(1)第一次sel选择值设为0,输出为递增波,从图中可以看出,输出的波形成线性递增,结果正确。
(2)第二次sel选择值设为1,输出为递减波,从图中可以看出,输出的波形成线性递减,结果正确。
(3)第三次sel的值设为2,输出为三角波,其仿真波形如下图所示,输出波形线性增大到最大后,再线性减小。
(4)第四次sel的值设为3,其输出的波形是阶梯波,其仿真波形见下图,波形递增常数为16,结果正确。
(5)第五次sel的值设为4,其输出的波形是正弦波,从图中可以看出,输出的数据的变化规律是正弦规律。
(6)第六次sel的值设为5,其输出的波形是方波,从图中仿真的结果可以看出,输出的波形变化规律是按方波规律周期性变化的。
(7)当设置为其他值时无波形输出
设计结论
本设计以函数信号发生器的功能为设计对象,运用EDA技术的设计方法,进行各种波形的输入设计、设计处理和器件编程。在VHDL语言的编写中按照语言描述规范,实现了几种波形的软件设计和具体逻辑元件结构的硬件映射。结合FPGA的开发集成环境Quartus2软件,产生了函数信号发生器的各种信号,同时完成了时序和功能仿真。从仿真及实验结果可以看出,本设计较好地满足了设计要求。同时,由于采用模块化的设计方法,系统中的各个电路均可独立实现各自的功能从而使系统具有较强的可移植性和维护性,这也为系统的功能扩展和升级提供了很大的便利。不足之处:系统上电后的状态不明确,若不按要求进行初始化操作会导致系统运行出现紊乱,进一步设计时可添加提示电路;以及个别的波形还不是太完美,还有一点缺陷,比如阶梯波。这次实验让我更大程度上加深了对硬件语言及数模转换电路的理解,特别是硬件语言所特有的并行性。使用者在使用之初,往往会由于原有的其他高级语言顺序编程思想的限制而犯错误。但是,当熟练后会发现,硬件语言的这一并行特性对于硬件的设计非常方便,且有助于提高系统的效率。另外有一点非常重要,那就是模块化的设计方法,它不仅有利于分工,而且有利于模块的移植和扩展。
参考文献:
[1] 汪烈军,黄志华. 电子设计自动化(EDA)实验指导书. 新疆大学信息科学与工程学院,2008
[2]刘江海.EDA技术.武汉:华中科技大学出版社,2009.5
[3]田耘,徐文波,张延伟.无线通信FPGA设计.北京:电子工业出版社,2007.10
[4]黄仁欣.EDA技术实用教程.北京:清华大学出版社,2006.9
[5]付家才.EDA工程实践技术.北京:化学工业出版社,2004.11
[6]黄智伟.FPGA系统设计与实践.北京:电子工业出版社,2005.1
展开阅读全文