EDA简易乐器演奏器.docx
《EDA简易乐器演奏器.docx》由会员分享,可在线阅读,更多相关《EDA简易乐器演奏器.docx(19页珍藏版)》请在冰豆网上搜索。
EDA简易乐器演奏器
1引言
随着电子技术的飞速发展,微电子技术的进步主要表现在大规模集成电路加工技术即半导体工艺技术的发展上,使得表征半导体的工艺水平的线宽已经达到了60nm,并在不断地缩小,面在硅片单位面积上,集成了更多的晶体管。
集成电路设计正在不断地向超大规模,极低功耗和超高速的方向发展,电子产品的功能越来越强大,体积越来越小,功耗越来越低。
同时,利用可编程逻辑器件和EDA技术使设计方法发生了质的变化。
把以前“电路设计+硬件搭试+调试焊接”转化为“功能设计+软件模拟+仿真下载”。
利用EDA开发平台,采用可编程逻辑器件CPLD/FPGA使硬件的功能可通过编程来实现,这种新的基于芯片的设计方法能够使设计者有更多机会充分发挥创造性思维,实现多种复杂数字逻辑系统的功能,将原来由电路板设计完成的工作放到芯片的设计中进行,减少了连线和体积,提高了集成度,降低了干扰,大大减轻了电路设计和PCB设计的工作量和难度,增强了设计的灵活性,有效地提高了工作效率,增加了系统的可靠性和稳定性,提高了技术指标。
这些技术使得各种电子产品迅速的进入了我们的生活,我们处在一个被电子产品深度包围的时代,在一个普通老百姓的家里,衣食住行,每一个产品的诞生都离不开EDA技术,从彩色电视机,到智能冰箱,到全自动洗衣机,电饭煲,到微波炉,电磁炉,电子琴,再到个人随身用的手机,MP3音乐播放器都需要EDA技术提供支持。
本文应用VHDL硬件描述语言,设计一个乐曲硬件演奏电路,它能将一首预先设置存储好的乐曲自动播放出来,除此之外,也能够通过按键的方式输入音符,使其具备简易电子琴的功能。
通过此项研究,能够深切的体会利用EDA工具开发的优越性,在此基础上,对乐曲硬件演奏电路功能进行丰富,具体一定的社会实用性。
2EDA技术
2.1简介
EDA技术是在电子CAD技术基础上发展起来的计算机软件系统,是指以计算机为工作平台,融合了应用电子技术、计算机技术、信息处理与智能化技术的最新成果,进行电子产品的自动设计。
利用EDA工具,电子设计师可以从概念、算法、协议等开始设计电子系统,大量工作可以通过计算机完成,并可以将电子产品从电路设计、性能分析到设计出IC版图或PCB版图的整个过程的计算机上自动处理完成。
现在对EDA的概念或畴用得很宽。
包括在机械、电子、通信、航空航天、化工、矿产、生物、医学、军事等各个领域,都有EDA的应用。
目前EDA技术已在各大公司、企事业单位和科研教学部门广泛使用。
例如在飞机制造过程中,从设计、性能测试与特性分析直到飞行模拟,都可能涉与到EDA技术。
本文所指的EDA技术,主要针对电子电路设计、PCB设计和IC设计。
2.2硬件描述语言——VHDL
2.2.1VHDL的简介
VHDL的英文全名是Very-High-SpeedIntegratedCircuitHardwareDescriptionLanguage,诞生于1982年。
1987年底,VHDL被IEEE和美国国防部确认为标准硬件描述语言。
VHDL语言是一种用于电路设计的高级语言,主要用于描述数字系统的结构,行为,功能和接口。
除了含有许多具有硬件特征的语句外,VHDL的语言形式和描述风格与句法是十分类似于一般的计算机高级语言。
VHDL的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件,一个电路模块或一个系统)分成外部(或称可是部分,与端口)和部(或称不可视部分),既涉与实体的部功能和算法完成部分。
在对一个设计实体定义了外部界面后,一旦其部开发完成后,其他的设计就可以直接调用这个实体。
2.2.2VHDL语言的特点
功能强大、设计灵活。
支持广泛、易于修改。
强大的系统硬件描述能力。
独立于器件的设计、与工艺无关。
很强的移植能力。
2.2.3VHDL的设计流程
用VHDL语言设计电路的流程:
在用VHDL语言来设计电路时,主要的过程是这样的:
(1)使用文本编辑器输入设计源文件。
(2)使用编译工具编译源文件。
VHDL的编译器有很多,ACTIVE公司,MODELSIM公司,SYNPLICITY公司,SYNOPSYS公司,VERIBEST公司等都有自己的编译器。
(3)功能仿真。
对于某些人而言,仿真这一步似乎是可有可无的。
但是对于一个可靠的设计而言,任何设计最好都进行仿真,以保证设计的可靠性。
另外,对于作为一个独立的设计项目而言,仿真文件的提供足可以证明你设计的完整性。
(4)综合。
综合的目的是在于将设计的源文件由语言转换为实际的电路。
这一部分的最终目的是生成门电路级的网表(Netlist)。
(5)布局、布线。
这一步的目的是生成用于烧写的编程文件。
在这一步,将用到第(4)步生成的网表并根据CPLD/FPG厂商的器件容量,结构等进行布局、布线。
这就好像在设计PCB时的布局布线一样。
先将各个设计中的门根据网表的容和器件的结构放在器件的特定部位。
然后,在根据网表中提供的各门的连接,把各个门的输入输出连接起来。
(6)最后仿真。
这一步主要是为了确定设计在经过布局布线之后,是不是还满足原本的设计要求。
3简易电子琴设计过程
3.1简易电子琴的工作原理
音乐产生原理与硬件设计由于一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。
该电子琴可以实现两个功能,用按键CS来选择不同功能,第一种功能是用手动即通过按键的形式输入不同音名,第二种功能是音乐发生器,可以自动重复播放儿童歌曲“种太阳”音乐。
当CS为高电平1时,选择功能二,当CS为低电平0时,选择功能一。
3.2简易电子琴的工作流程图
3.3简易电子琴中各模块的设计
系统部结构图如图3.1所示
图3.1
3.3.1分频器fpq1模块
1.分频器1的程序
libraryieee;
useieee.std_logic_1164.all;
entityfpq1is
port(clk12:
instd_logic;
clk1:
bufferstd_logic);
endfpq1;
architecturebhvoffpq1is
begin
process(clk12)
variablecount:
integerrange0to1200;
begin
ifclk12'eventandclk12='1'then
count:
=count+1;
ifcount=1200then
clk1<=notclk1;count:
=0;
endif;endif;
endprocess;
endbhv;
2.分频器1的仿真图
3.3.2分频器fpq2模块程序
1.分频器2的程序
libraryieee;
useieee.std_logic_1164.all;
entityfpq2is
port(clk1:
instd_logic;
clk2:
bufferstd_logic);
endfpq2;
architecturebhvoffpq2is
begin
process(clk1)
variablecount:
integerrange0to500;
begin
ifclk1'eventandclk1='1'then
count:
=count+1;
ifcount=500then
clk2<=notclk2;count:
=0;
endif;endif;
endprocess;
endbhv;
2.分频器2的仿真图
3.3.3琴/乐功能选择器bmux模块程序
1.功能选择器的程序
libraryieee;
useieee.std_logic_1164.all;
entitybmuxisport(
index1:
instd_logic_vector(3downto0);
index2:
instd_logic_vector(3downto0);
cs:
instd_logic;
toneindex:
outstd_logic_vector(3downto0));
end;
architecturebhvofbmuxis
begin
process(cs)
begin
casecsis
when'0'=>toneindex<=index1;
when'1'=>toneindex<=index2;
whenothers=>toneindex<=null;
endcase;
endprocess;
endbhv;
3.3.2乐曲自动演奏notetabs模块程序
libraryieee;
useieee.std_logic_1164.all;
entitynotetabsis
port(clk:
instd_logic;
toneindex2:
outstd_logic_vector(3downto0));
endnotetabs;
architectureoneofnotetabsis
signalcounter:
integerrange0to138;
begin
process(clk)
begin
ifcounter=138then
counter<=0;
elsifclk'eventandclk='1'then
counter<=counter+1;
endif;
endprocess;
process(counter)
begin
casecounteris
when00=>toneindex2<="0101";when01=>toneindex2<="0110";
when02=>toneindex2<="0101";when03=>toneindex2<="0101";
when04=>toneindex2<="1011";when05=>toneindex2<="1011";
when06=>toneindex2<="1001";when07=>toneindex2<="1001";
when08=>toneindex2<="0101";when09=>toneindex2<="0110";
when10=>toneindex2<="0101";when11=>toneindex2<="0101";
when12=>toneindex2<="1011";when13=>toneindex2<="1011";
when14=>toneindex2<="1001";when15=>toneindex2<="1001";
when16=>toneindex2<="0011";when17=>toneindex2<="0100";
when18=>toneindex2<="0101";when19=>toneindex2<="0101";
when20=>toneindex2<="0101";when21=>toneindex2<="0101";
when22=>toneindex2<="1001";when23=>toneindex2<="1001";
when24=>toneindex2<="0101";when25=>toneindex2<="0101";
when26=>toneindex2<="0111";when27=>toneindex2<="0110";
when28=>toneindex2<="0110";when29=>toneindex2<="0110";
when30=>toneindex2<="0000";when31=>toneindex2<="0000";
when32=>toneindex2<="0100";when33=>toneindex2<="0100";
when34=>toneindex2<="1010";when35=>toneindex2<="1010";
when36=>toneindex2<="0111";when37=>toneindex2<="0111";
when38=>toneindex2<="0010";when39=>toneindex2<="0011";
when40=>toneindex2<="0100";when41=>toneindex2<="0100";
when42=>toneindex2<="1001";when43=>toneindex2<="1001";
when44=>toneindex2<="0111";when45=>toneindex2<="0111";
when46=>toneindex2<="0111";when47=>toneindex2<="0110";
when48=>toneindex2<="0101";when49=>toneindex2<="0101";
when50=>toneindex2<="0110";when51=>toneindex2<="0111";
when52=>toneindex2<="1001";when53=>toneindex2<="1001";
when54=>toneindex2<="0101";when55=>toneindex2<="0110";
when56=>toneindex2<="0101";when57=>toneindex2<="0100";
when58=>toneindex2<="0011";when59=>toneindex2<="0011";
when60=>toneindex2<="0000";when61=>toneindex2<="0000";
when62=>toneindex2<="0101";when63=>toneindex2<="0110";
when64=>toneindex2<="0101";when65=>toneindex2<="0101";
when66=>toneindex2<="1011";when67=>toneindex2<="1011";
when68=>toneindex2<="1001";when69=>toneindex2<="1001";
when70=>toneindex2<="0101";when71=>toneindex2<="0110";
when72=>toneindex2<="0101";when73=>toneindex2<="0101";
when74=>toneindex2<="1011";when75=>toneindex2<="1011";
when76=>toneindex2<="1001";when77=>toneindex2<="1001";
when78=>toneindex2<="0101";when79=>toneindex2<="0110";
when80=>toneindex2<="0111";when81=>toneindex2<="0111";
when82=>toneindex2<="0111";when83=>toneindex2<="0111";
when84=>toneindex2<="1001";when85=>toneindex2<="1010";
when86=>toneindex2<="1011";when87=>toneindex2<="1011";
when88=>toneindex2<="1100";when89=>toneindex2<="1011";
when90=>toneindex2<="1010";when91=>toneindex2<="1010";
when92=>toneindex2<="0000";when93=>toneindex2<="0000";
when94=>toneindex2<="0010";when95=>toneindex2<="0011";
when96=>toneindex2<="0100";when97=>toneindex2<="0100";
when98=>toneindex2<="1010";when99=>toneindex2<="1010";
when100=>toneindex2<="0111";when101=>toneindex2<="0111";
when102=>toneindex2<="0010";when103=>toneindex2<="0011";
when104=>toneindex2<="0100";when105=>toneindex2<="0100";
when106=>toneindex2<="1010";when107=>toneindex2<="1010";
when108=>toneindex2<="0111";when109=>toneindex2<="0111";
when110=>toneindex2<="0111";when111=>toneindex2<="0110";
when112=>toneindex2<="0101";when113=>toneindex2<="0101";
when114=>toneindex2<="0101";when115=>toneindex2<="0101";
when116=>toneindex2<="0110";when117=>toneindex2<="0110";
when118=>toneindex2<="0111";when119=>toneindex2<="0111";
when120=>toneindex2<="1010";when121=>toneindex2<="1010";
when122=>toneindex2<="1010";when123=>toneindex2<="1010";
when124=>toneindex2<="1010";when125=>toneindex2<="1010";
when126=>toneindex2<="0101";when127=>toneindex2<="0101";
when128=>toneindex2<="1001";when129=>toneindex2<="1001";
when130=>toneindex2<="0000";when131=>toneindex2<="0000";
when132=>toneindex2<="0000";when133=>toneindex2<="0000";
when134=>toneindex2<="0000";when135=>toneindex2<="0000";
when136=>toneindex2<="0000";when137=>toneindex2<="0000";
when138=>toneindex2<="0000";whenothers=>null;
endcase;
endprocess;
endone;
3.3.3按键tone模块程序
libraryieee;
useieee.std_logic_1164.all;
entitytoneis
port(key:
instd_logic_vector(6downto0);
toneindex1:
outstd_logic_vector(3downto0));
end;
architectureoneoftoneis
begin
search:
process(key)
begin
casekeyis
when"0000001"=>toneindex1<="0001";
when"0000010"=>toneindex1<="0010";
when"0000100"=>toneindex1<="0011";
when"0001000"=>toneindex1<="0100";
when"0010000"=>toneindex1<="0101";
when"0100000"=>toneindex1<="0110";
when"1000000"=>toneindex1<="0111";
whenothers=>toneindex1<="0000";
endcase;
endprocess;
end;
3.3.4tonetaba模块程序
libraryieee;
useieee.std_logic_1164.all;
entitytonetabais
port(index:
instd_logic_vector(3downto0);
code:
outstd_logic_vector(3downto0);
high:
outstd_logic;
tone:
outstd_logic_vector(10downto0));
end;
architectureoneoftonetabais
begin
process(index)
begin
caseindexis--译码电路,查表方式,控制音调的预置数
when"0000"=>tone<="";code<="0000";high<='0';--2047
when"0001"=>tone<="";code<="0001";high<='0';--773;
when"0010"=>tone<="";code<="0010";high<='0';--912;
when"0011"=>tone<="";code<="0011";high<='0';--1036;
when"0100"=>tone<="";code<="0100";high<='0';--1116;
when"0101"=>tone<="";code<="0101";high<='0';--1197;
when"0110"=>tone<="";code<="0110";high<='0';--1290;
when"0111"=>tone<="";code<="0111";high<='0';--1372;
when"1000"=>tone<="";code<="0001";high<='1';--1410;
when"1001"=>tone<="";code<="0010";high<='1';--1480;
when"1010"=>tone<="";code<="0011";high<='1';--1542;
when"1100"=>tone<="";code<="0101";high<='1';--1622;
when"1101"=>tone<="";code<="0110";high<='1';--16