摘要:文中介绍了电子琴系统的整体设计,并基于超高速硬件描述语言VHDL在Xilinx公司的SpartanⅡ系列的2sc200PQ208-5芯片上编程实现.电子琴系统的设计包含四个模块,分别是控制输入电路、FPGA、显示电路和扬声器电路。其中FPGA模块的设计是整个电子琴系统设计的核心内容。四个模块的有机组合完成了电子琴自动演奏的功能。文中还详细介绍了FPGA功能模块的原理及其工作时序仿真图。本产品的特点是成本较低,性能稳定,精度高,有一定的开发价值。关键词:现场可编程逻辑器件FPGA超高速硬件描述语言VHDL电子琴系统自动演奏8.18.4程序设计与仿真电子琴VHDL程序包含有:顶层程序、音阶发生器程序、数控分频模块程序和自动演奏模块程序。1.顶层程序与仿真(1)顶层VHDL程序--文件名:top.vhd--功能:顶层文件--最后修改日期:2004.3.20libraryIEEE;useIEEE.STD_LOGIC_1164.ALL;useIEEE.STD_LOGIC_ARITH.ALL;useIEEE.STD_LOGIC_UNSIGNED.ALL;entitytopisPort(clk32MHz:instd_logic;--32MHz系统时钟handTOauto:instd_logic;--键盘输入/自动演奏code1:outstd_logic_vector(6downto0);--音符显示信号index1:instd_logic_vector(7downto0);--键盘输入信号high1:outstd_logic;--高低音节信号spkout:outstd_logic);--音频信号endtop;architectureBehavioraloftopiscomponentautomusicPort(clk:instd_logic;Auto:instd_logic;index2:instd_logic_vector(7downto0);index0:outstd_logic_vector(7downto0));endcomponent;componenttonePort(index:instd_logic_vector(7downto0);code:outstd_logic_vector(6downto0);high:outstd_logic;tone0:outintegerrange0to2047);endcomponent;componentspeakerPort(clk1:instd_logic;tone1:inintegerrange0to2047;spks:outstd_logic);endcomponent;signaltone2:integerrange0to2047;signalindx:std_logic_vector(7downto0);beginu0:automusicportmap(clk=clk32MHZ,index2=index1,index0=indx,Auto=handtoAuto);u1:toneportmap(index=indx,tone0=tone2,code=code1,high=high1);u2:speakerportmap(clk1=clk32MHZ,tone1=tone2,spks=spkout);endBehavioral;(2)仿真顶层文件仿真图如图8.18.2所示。图8.18.2顶层文件仿真图2.音阶发生器程序与仿真(1)音阶发生器VHDL程序--文件名:tone.vhd。--功能:libraryIEEE;useIEEE.STD_LOGIC_1164.ALL;useIEEE.STD_LOGIC_ARITH.ALL;useIEEE.STD_LOGIC_UNSIGNED.ALL;entitytoneisPort(index:instd_logic_vector(7downto0);--音符输入信号code:outstd_logic_vector(6downto0);--音符显示信号high:outstd_logic;--高低音显示信号tone0:outintegerrange0to2047);--音符的分频系数endtone;architectureBehavioraloftoneisbeginsearch:process(index)--此进程完成音符到音符的分频系数译码,音符的显示,高低音阶begincaseindexiswhen00000001=tone0=773;code=1001111;high='1';when00000010=tone0=912;code=0010010;high='1';when00000100=tone0=1036;code=0000110;high='1';when00001000=tone0=1116;code=1001100;high='1';when00010000=tone0=1197;code=0100100;high='1';when00100000=tone0=1290;code=0100000;high='0';when01000000=tone0=1372;code=0001111;high='0';when10000000=tone0=1410;code=0000000;high='0';whenothers=tone0=2047;code=0000001;high='0';endcase;endprocess;endBehavioral;(2)音阶发生器程序仿真音阶发生器程序仿真图如图8.18.3所示。图8.18.3音阶发生器仿真图3.数控分频模块程序与仿真(1)数控分频模块VHDL程序--文件名:speaker.vhd。--功能:实现数控分频。--最后修改日期:20004.3.19。libraryIEEE;useIEEE.STD_LOGIC_1164.ALL;useIEEE.STD_LOGIC_ARITH.ALL;useIEEE.STD_LOGIC_UNSIGNED.ALL;entityspeakerisPort(clk1:instd_logic;--系统时钟tone1:inintegerrange0to30624;--音符分频系数spks:outstd_logic);--驱动扬声器的音频信号endspeaker;architectureBehavioralofspeakerissignalpreclk,fullspks:std_logic;beginpulse1:process(clk1)--此进程对系统时钟进行4分频variablecount:integerrange0to8;beginifclk1'eventandclk1='1'thencount:=count+1;ifcount=2thenpreclk='1';elsifcount=4thenpreclk='0';count:=0;endif;endif;endprocesspulse1;genspks:process(preclk,tone1)--此进程按照tone1输入的分频系数对8MHz的脉冲再次分频,得到所需要的音符频率variablecount11:integerrange0to30624;beginifpreclk'eventandpreclk='1'thenifcount11tone1thencount11:=count11+1;fullspks='1';elsecount11:=0;fullspks='0';endif;endif;endprocess;delaysps:process(fullspks)--此进程对fullspks进行2分频variablecount2:std_logic:='0';beginiffullspks'eventandfullspks='1'thencount2:=notcount2;ifcount2='1'thenspks='1';elsespks='0';endif;endif;endprocess;endBehavioral;(2)数控分频模块程序仿真数控分频模块程序仿真图如图8.18.4所示。图8.18.4数控分频模块仿真图4.自动演奏模块程序与仿真(1)自动演奏模块VHDL程序--文件名:automusic.vhd--功能:实现自动演奏功能。--最后修改日期:2004.3.19。libraryIEEE;useIEEE.STD_LOGIC_1164.ALL;useIEEE.STD_LOGIC_ARITH.ALL;useIEEE.STD_LOGIC_UNSIGNED.ALL;entityautomusicisPort(clk,Auto:instd_logic;--系统时钟;键盘输入/自动演奏index2:instd_logic_vector(7downto0);--键盘输入信号index0:outstd_logic_vector(7downto0));--音符信号输出endautomusic;architectureBehavioralofautomusicissignalcount0:integerrange0to31;--changesignalclk2:std_logic;beginpulse0:process(clk,Auto)--此进程完成对系统时钟8M的分频,得到4Hz的信号clk2variablecount:integerrange0to8000000;beginifAuto='1'thencount:=0;clk2='0';elsifclk'eventandclk='1'thencount:=count+1;ifcount=4000000(4)thenclk2='1';elsifcount=8000000(8)thenclk2='0';count:=0;endif;endif;endprocess;music:process(clk2)--此进程完成自动演奏部分曲的地址累加beginifclk2'eventandclk2='1'thenifcount0=31thencount0=0;elsecount0=count0+1;endif;endif;endprocess;com1:process(count0,Auto,index2)beginifAuto='0'thencasecount0is--此case语句:存储自动演奏部分的曲when0=index0=00000100;--3when1=index0=00000100;--3when2=index0=00000100;--3when3=index0=00000100;--3when4=index0=00010000;--5when5=index0=00010000;--5when6=index0=00010000;--5when7=index0=00100000;--6when8=index0=10000000;--8when9=index0=10000000;--8when10=index0=10000000;--8when11=index0=00000100;--3when12=index0=00000010;--2when13=index0=00000010;--2when14=index0=00000001;--1when15=index0=00000001;--1when16=index0=00010000;--5when17=index0=00010000;--5when18=index0=00001000;--4when19=index0=00001000;--4when20=index0=00001000