用VHDL语言设计简易电子琴演奏.docx
- 文档编号:12132172
- 上传时间:2023-04-17
- 格式:DOCX
- 页数:20
- 大小:256.62KB
用VHDL语言设计简易电子琴演奏.docx
《用VHDL语言设计简易电子琴演奏.docx》由会员分享,可在线阅读,更多相关《用VHDL语言设计简易电子琴演奏.docx(20页珍藏版)》请在冰豆网上搜索。
用VHDL语言设计简易电子琴演奏
基于VHDL语言设计简易电子琴演奏电
路
摘要:
生活中一首简单的歌也要遵循基本的乐理知识,歌曲要有固定的节拍,即每多少分音符为一拍,每小节几拍。
因此,拍子是音乐中最重要的组成部分,本课程设计主要采用EDA技术,基于VHDL语言设计一个简易的八音符电子琴,并且可以选择通过按键输入或者自动演奏来奏出存入的乐曲。
课程设计中,程序运行平台为MAX+plusIIo根据音符的分频预置数来弹奏出不同的音符,将演奏出的《小红帽》既而再通过各个子模块,编程,仿真,达到最终的验证。
关键字:
EDA;VHDL;电子琴;音符;频率
一、设计说明
(1)EDA的技术及其发展
当今世界,电子技术有了突飞猛进的发展,这使得现代电子产品融入并运用于各个领域,其性能也在逐步地提高。
现代电子技术的核心是EDA,EDA是电子设计自动化(ElectronicDesignAutomation)缩写,是90年代初从CAD、CAM、CAT和CAE的概念发展而来的,以硬件描述语言为系统逻辑描述的主要表达方式,并以计算机、大规模可编程逻辑器件的开发软件及实验开发系统为设计工具,通过有关的开发软件,自动完成用软件的方式设计电子系统到硬件系统。
EDA工具从数字系统设计的单一领域,发展到今天,应用范围已涉及模拟、微波等多个领域,包括在机械、电子、通信、航空航天、化工、矿产、生物、医学、军事等各个领域,都有EDA的应用。
可以说,EDA技术为现代电子理论和设计的表达与实现提供了可能。
(2)VHDL语言的特点
常用硬件描述语言有VHDL、Verilog和ABEL语言,其中VHDL语言用的较为广泛,它的全英文名VHSIC(VeryHighSpeedIntegratedCircuit)HardwareDescriptionLanguage,是以高级描述语言,系统级仿真和综合技术为特点,采用“自顶向下”的设计理念,VHDL具有很强的电路描述和建模能力,能从多
个层次对数字系统进行建模和描述,从而大大简化了硬件设计任务,提高了设计效率和可靠性。
VHDL的结构特点是将设计实体的内部功能和算法完成部分。
相对于其他硬件语言,VHDL有许多优点。
比如VHDL的行为描述能力更强,而且具有丰富的仿真语句和库函数,随时可对系统进行仿真模拟,使设计者对整个工程的结构和功能可行性做出判断。
二、设计目的
生活中,我们离不开音乐,由和谐的音调组成的各种美妙动听的音乐给我们带来了听觉上得享受和精神上的放松,可知,一首简单的歌也要遵循基本的乐理知识,歌曲要有固定的节拍,即每多少分音符为一拍,每小节几拍。
因此,拍子是音乐中最重要的组成部分,日常生活中的音乐需要由乐器来演奏,在众多乐器中,电子琴较特殊,它是以一种合成的键盘乐器,类似于钢琴,但要依靠电源才能工作。
如图一所示为电子琴,但归根到底其结构也是由基本的编程以及电路所构成。
图一
在本课程中,将要运用本学期所学的VHDL语言设计一个简易的电子琴来演
奏音乐,设计的主要目的有以下两点:
1、通过课程设计,加深理解,能够更深地掌握这门课所学的知识,以及掌握和运用MAX+PLUSII软件,以便在以后的生活学习中能够得心应手进行其他的设计。
2、通过编程,波形仿真,以培养开动脑筋,自主能动性以及学会思考问题,学会动手的能力,通过理论与实践的结合学会在以后的生活中可以自如地将所学习的知识运用到实际。
三、设计整体思路及原理
(一)设计思路
本课程设计主要是基于VHDL文本输入法设计乐曲演奏电路,在大二期间,
《数字电路与分析》这门专业课中也做过音乐发生器的设计性实验,而这次课程设计,由于硬件设备等缺陷,硬件部分的测试将无法完成,于是实验中主要考察对软件编程的能力。
在课本《EDA技术》的P251页中,有一个“乐曲硬件演奏”的实验,该实验中用到三个子模块,而我所设计的“简易八音符电子琴演奏电路”与次实验很相似,也要涉及到类似的三个子模块,但是,相比之下,我所设计的电路新增加一个功能,即“电子琴可以自动播放音乐,在演奏乐曲中,通过AUTO子模块既可以用手动弹奏键盘输入音乐,也可以选择自动演奏”。
由前面所述可知,一首乐曲的节拍频率很重要,因此在编程时应当要考虑到每一个音符所占的时钟节拍。
课本中采用的是优美动听的中国古典音乐《梁祝》这首曲子,我决定在程序中填入《小红帽》这首琅琅上口的儿歌,它的节奏感比较鲜明,曲长较短,每个音符几乎都涉及到,并且简单易懂。
由乐理知识可知,
《小红帽》是一首2/4拍的歌曲,即:
“以四分音符为一拍,每小节两拍”。
图二是选自《小红帽》歌曲中前八小节的简谱:
《小红帽》
2/4节拍
图二
以上是整个歌曲的部分简谱,从中可以看出,每一小节的是两拍,如果令一个时钟周期CLK为一拍,那么可知在第一小节中,音符1和2个占1/2拍,3和4也是同理。
若定义一个时钟周期是1S,那么1、2、3、4各时占0.5So
根据歌曲的节拍频率,可知音符的持续时间需要根据乐曲的速度计每个音符的拍数来确定,所以需要给每一个音符设定分频预置数,由课本中可知,每一个音符都有固定分频预置数,在本首歌曲中,出现的音符一共有1,2,3,4,5,6,8(8为简谱中的高音do),查表可得,他们的分频预置数分别为:
音符
分频预置数
1
773
2
912
3
1036
4
1116
5
1197
6
1290
8
1410
图三
根据上表中所示的预置分频数,就可以区分不出不同的音符,既而可以在键盘上输入自己想要的音乐。
(二)设计原理
经过分析之后,可知课程设计所需要三个子模块,它们分别是:
•乐曲自动演奏模块
•发音模块
•分频模块
1、乐曲自动演奏模块
此模块主要用来产生想要演奏的音乐,而在程序中,软件不能够辨认出简谱,而是信号,因为基本的音符是8个,因此,对于输入的每一个音符,都设置成4位发生控制输入信号。
将他们输入,电脑便根据4位2进制的值来确定相对应的音符,还有一点应当注意:
此模块输入音乐有两种方式,可以同步演奏也可以自动演奏,这需要有AUT0(0或1)的值来确认,总之,AUTO的主要目的是将二进制信号转化为能够发声的音乐。
2、发音模块
此模块主要是产生音符的分频预置数,根据不同的音符产生不同的分频预置数,分频预置值控制数控分频模块进行分频,由此得到每个音符对应的频率。
该模块的输入信号INDEX是为上一个模块的输出INDEXO,且高低音显示信号HIGH和音符分频系数都是根据音符输入确定的。
比如INDEX为1是,表示弹奏了一个do,它的分频系数则为773Hz,音符显示信号为1001111,是773的二进制表示,此时高低音显示0表示低音。
3、分频模块
此模块主要是对时基脉冲进行分频,得到与0、1、2、3、4、5、6、8八个音符相对应的频率。
首先根据时钟信号输入得到时基脉冲及计数器的值,然后将时基脉冲值转化为音符的频率。
三个子模块的总体流程如下:
图四
四、设计要求
在课程设计的过程中,对自己提出以下要求:
1、在设计之前,首先要了解设计所需要的相关背景知识,并掌握所设计题目的原理。
2、在设计的过程中,要弄设计实验的整个流程,根据原理设计子模块,并对每一个子模块认真地编写程序,编程的过程中要随时查阅相关资料,遇到不懂得问题应积极解决,再及时地询问老师或同学。
3、仿真时当遇到程序错误导之仿真失败时,应立即寻找失败原因,及时发现错
误并改正。
五、设计流程
在对上述三个模块做了初步的解释后,接下来的工作即对每一个子模块进行
编程:
(一)乐曲自动演奏模块的图形及程序如下:
LIBRARYIEEE;
USEIEEE.STD_L0GIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYAUTOIS
PORT(CLK:
INSTD_LOGIC:
一系统时钟信号
AUTO:
INSTD_LOGIC;一键盘输入/自动演奏
CLK2:
BUFFERSTD_LOGIC;—时钟输出
INDEX2:
INSTD_L0GIC_VECT0R(3DOWNTO0):
—键盘输入信号
INDEXO:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));—音符信号输出
ENDAUTO;
ARCHITECTUREBEHAVIORALOFAUTOIS
SIGNALCOUNTO:
INTEGERRANGE0TO47;一定义信号计数器,有47个信号元素
BEGIN
PULSEO:
PROCESS(CLK,AUTO)—PULSEO工作进程开始
VARIABLECOUNT:
INTEGERRANGE0TO8;一定义变量计数器,从0到
8
BEGIN
—键盘输入为1
IFAUTO='l'then
COUNT:
=0;CLK2〈='O';一计数器值为0,时钟信号
2幅值为0
elsifCclk*eventandclk=;r)then—输入的时钟信号为其他值COUNT:
=COUNT+1;一计数器加1即为1
IFCOUNT=1THEN
CLK2〈=T';
ELSIFC0UNT=2THEN
CLK2〈='0';COUNT:
=0;
ENDIF;
ENDIF;
ENDPROCESS;
MUSIC:
PROCESS(CLK2)—MUSIC工作进程开始
BEGIN
IF(CLK2*EVENTANDCLK2=*1')THEN—时钟信号2为1IF(C0UNT0=47)THEN—计数器值为47
C0UNT0<=0;一计数器清0
ELSE
COUNTO<=COUNTO+1;
ENDIF;
ENDIF;
ENDPROCESS;
COMI:
PROCESS(COUNTO,AUTO,INDEX2)
BEGIN
IFAUTO='O'THEN一键盘输入为0
CASECOUNTOIS一由计数器从0到47的取值判断音符信号的
8位二进制数
WHEN0=〉INDEX0〈="0001”;—1
WHEN1=〉INDEXO〈="OO1O”;—2
WHEN2=〉INDEX0〈="0011”;—3
WHEN3=〉INDEX0〈="0100”;—4
WHEN4=〉INDEX0〈="0101”;—5
WHEN5=>INDEX0<=/,010r,;—5
WHEN6=〉INDEX0〈="0011”;—3
WHEN7=>INDEX0<=/,000r,;—1
WHEN8=〉INDEX0〈="1000”;—8
WHEN9=>INDEX0<=/,1000/,;—8
WHEN10=〉INDEX0〈="0110”;—6
WHEN11=>INDEXO<=/,O1OO//;—4
WHEN12=>INDEX0<=/,010r/;—5
WHEN13=〉INDEX0〈="0101”;一5
WHEN14=〉INDEX0〈="0011”;—3
WHEN15=〉INDEX0〈="0011”;—3
WHEN16=〉INDEX0〈="0001”;—1
WHEN17=>INDEX0〈="0010”;—2
WHEN18=〉INDEX0〈="0011”;—3
WHEN19=〉INDEX0〈="0100”;—4
WHEN20=〉INDEX0〈="0101”;—5
WHEN21=〉INDEX0〈="0011”;—3
WHEN22=〉INDEX0〈="0010”;—2
WHEN23=〉INDEX0〈="0001”;—1
WHEN24=〉INDEX0〈="0010”;—2
WHEN25=〉INDEX0〈="0010”;—2
WHEN26=〉INDEX0〈="0011”;—3
WHEN27=〉INDEX0〈="0011”;—3
WHEN28=>INDEX0<=/,0010//;—2
WHEN29=〉INDEX0〈="0010”;—2
WHEN30=〉INDEX0〈="0101”;—5
WHEN31=〉INDEX0〈="0101”;—5
WHEN32=〉INDEX0〈="0001”;—1
WHEN33=〉INDEX0〈="0010”;—2
WHEN34=〉INDEX0〈="0011”;—3
WHEN35=〉INDEX0〈="0100”;—4
WHEN36=〉INDEX0〈="0101”;—5
WHEN37=〉INDEX0〈="0101”;—5
WHEN38=>INDEX0<=/z0011";—3
WHEN39=〉INDEX0〈="0001”;—1
WHEN40=>INDEX0<=/,1000/,;—8
WHEN41=>INDEX0<=/,1000/,;—8
WHEN42=〉INDEX0〈="0110”;一6
WHEN43=>INDEX0<=/,0100/,;—4
WHEN44=〉INDEX0〈="0101”;—5
WHEN45=〉INDEX0〈="0101”;—5
WHEN46=>INDEX0〈="0011”;—3
WHEN47=〉INDEX0〈="0011”;—3
WHENOTHERS=>NULL;
ENDCASE;
ELSEINDEX0<=INDEX2;一将音符信号0的值赋给音符信号2
ENDIF;
ENDPROCESS;
ENDBEHAVIORAL;
程序说明:
由程序可知,AUTO为低电平有效,当AUTO为“1”时,此时为手动输入音乐演奏,当AUTO为“0”时,为自动输入演奏,当确定了时钟信号输出的值后,在第二个PROCESS中就可以由它控制4位发声控制输入信号了。
即CLK2的值为0时,COUNTO为lo最后的COM1便是由前两个PROCESS所确定的COUNTO,AUTO和键盘输入信号值INDEX2将4位的二进制数转化为音符信号的输出,达到自动演奏的目的。
(二)发音模块的图形及程序如下:
LIBRARYIEEE;
USEIEEE.STD_L0GIC_1164.ALL;
USEIEEE.STD一LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYTONEIS
PORT(INDEX:
INSTD_LOGIC_VECTOR(3DOWNTO0);一音符输入信号
CODE:
OUTSTD_L0GIC_VECT0R(6DOWNTO0);—音符显示信号HIGH:
OUTSTD_LOGIC;一高低音显示信号
TONEO:
OUTINTEGERRANGE0TO2047);一音符的分频系数
ENDTONE;
ARCHITECTUREARTOFTONEIS
BEGIN
SEARCH:
PROCESS(INDEX)
BEGIN
CASEINDEXISWHEN"0001”=〉TONE0〈=773;CODE〈="1001111”;HIGH〈='O';WHEN"0010”=〉TONE0〈=912;CODE<="0010010”;HIGH〈='O';WHEN"0011”=〉TONE0〈=1036;CODE〈="0000110";HIGH<='O';WHEN"0100”=〉TONE0〈=1116;CODE〈="1001100";HIGH<='O';WHEN"0101”=>TONEO〈=1197;CODE〈="0100100";HIGH〈='O';WHEN"0110”二〉T0NE0〈=1290;CODE〈项'0100000”;HIGH〈='O';WHEN"0111”=〉TONE0〈=1372;CODE〈="0001111”;HIGH<='O';WHEN"1000”二〉T0NE0〈=1410;CODE〈项'0000000”;HIGH〈='1';
WHENOTHERS=〉TONE0〈=2047;CODE<="0000001”;HIGH〈='O';
ENDCASE;
ENDPROCESS;
ENDART;
程序说明:
INDEX为输入的音乐,CODE显示分频预置数,当HIGH为“1”时,表示高了8度,为“0”时,表示低音。
(三)分频模块的图形及其程序如下:
LIBRARYIEEE;
USEIEEE.STD_L0GIC_1164.ALL;
USEIEEE.STD^LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYFENPINIS
PORT(CLK1:
INSTD_LOGIC;一系统时钟信号
TONE1:
ININTEGERRANGE0TO2047;一音符分频系数
SPKS:
OUTSTD_LOGIC):
一驱动扬声器音频信号
ENDENTITYFENPIN;
ARCHITECTUREARTOFFENPINIS
SIGNALPRECLK:
STD_LOGIC;一定义时基脉冲信号
SIGNALFULLSPKS:
STD_LOGIC;
BEGIN
PROCESS(CLK1)
VARIABLECOUNT:
INTEGERRANGE0TO8;
BEGIN
IF(CLK1'EVENTANDCLK1=T')THEN一时钟信号为1
COUNT:
=COUNT+1;一计数器取值为1
IFC0UNT=2THEN
PRECLK〈=T';
ELSIFCOUNT=4THEN—计数器为4
PRECLKV'O';COUNT:
=0;一时基脉冲为0,计数器清0
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(PRECLK,T0NE1)
VARIABLEC0UNT11:
INTEGERRANGE0TO2047;
BEGIN
IF(PRECLK'EVENTANDPRECLK=*1')THEN
IFCOUNT1KT0NE1THEN
C0UNT11:
=COUNT11+1:
FULLSPKS<=;1';
ELSE
COUNT11:
=O;FULLSPKS<=*O';
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(FULLSPKS)
VARIABLEC0UNT2:
STD_LOGIC:
='O';
BEGIN
IF(FULLSPKS'EVENTANDFULLSPKS=T')THEN一音频信号输出上升沿有效
C0UNT2:
=NOTC0UNT2:
IFC0UNT2='l'THEN
spks<='r;
ELSE
SPKS〈='O';
ENDIF;
ENDIF;
ENDPROCESS:
ENDART;
程序说明:
注意最后一个PROCESS则是用来设置扬声器输出信号的,扬声器信号由0和1控帯U,当且仅当前一个PROCESS中的FULLSPKS输出为1时,扬声器才有输出,再根据计数器取值来确定输出是1还是0
(四)顶层电路的图形及其程序:
LIBRARYIEEE;
USEIEEE.STD_L0GIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYDIANZIQINIS
PORT(CLK:
INSTD_LOGIC;一系统时钟信号
HANDTOAUTO:
INSTD_LOGIC;一键盘输入/自动演奏信号
CODE1:
OUTSTD_LOGIOECTOR(6DOWNTO0):
—音符显示信号
INDEX1:
INSTD_L0GIC^VECT0R(3DOWNTO0);一键盘输入信号
HIGH1:
OUTSTD_LOGIC;一高低音节信号
SPROUT:
OUTSTD_LOGIC):
一音频信号
END;
ARCHITECTUREARTOFDIANZIQINIS
COMPONENTAUTO—引用AUTO元件
PORT(CLK:
INSTD_LOGIC:
AUTO:
INSTD_LOGIC;一输入自动演奏信号
INDEX2:
INSTD_LOGIC_VECTOR(3DOWNTO0);—输入4位控制信号
INDEXO:
OUTSTD_LOGIC_VECTOR(3D0WNT00));—输出8位的音符ENDCOMPONENT;
COMPONENTTONE—引用TONE元件
PORT(INDEX:
INSTD_L0GIC_VECT0R(3DOWNTO0);
CODE:
OUTSTD_L0GIC_VECT0R(6DOWNTO0):
HIGH:
OUTSTD_LOGIC:
TONEO:
OUTINTEGERRANGE0TO2047);
ENDCOMPONENT;
COMPONENTFENPIN—引用FENPIN元件
PORT(CLK1:
INSTD_LOGIC;
T0NE1:
ININTEGERRANGE0TO2047;
SPKS:
OUTSTD_LOGIC);
ENDCOMPONENT;
SIGNALT0NE2:
INTEGERRANGE0TO2047;一定义主程序音调频率信号
SIGNALINDX:
STD_LOGIC_VECTOR(7DOWNTO0);一定义8位的音符信号
BEGIN
UO:
AUTO
PORTMAP(CLK=>CLK,INDEX2=>INDEX1,INDEXO=>INDX,AUTO=>HANDTOAUTO);一调用自动演奏模块
U1:
TONE
PORTMAP(INDEX=>INDX,T0NE0=>T0NE2,CODE=>CODE1,HIGH=>HIGH1):
—调用音调发生模块
U2:
FENPIN
PORTMAP(CLK1=>CLK,TONE1=>TONE2,SPKS=>SPKOUT);—调用数控分频模块ENDART;
程序说明:
该顶层模块是整个设计的核心,并且是VHDL程序的主程序,通过调用子程序最终实现乐曲演奏的目的,奏出《小红帽》。
利用VHDL语言
COMPONENT将三个模块组合起来,其中3个模块和DIANZIQIN模块的输入输出是——对应的,比如AUTO对应HANDTOAUTO,TONEO对应TONE2,SPKS对应SPKOUTo
可知总体电路图为:
六、仿真波形图
(—)乐曲自动演奏模块的波形图:
可知它分为了两种情况,我们分别用两个波形图来解释说明:
1、当为自动演奏音乐时的波形如下:
说明:
可知此时,INDEX。
以及计数器COUNTO和COUNT都和时钟输入CLK2有关,而此时,INDEXO和INDEX2无需时序一致,因为在自动演奏的情况下,是先将音
乐输入,然后通过播放来自动演奏,AUTO始终为高电平,而CLK只是一个系统时钟,控制着输入端口INDEX2的节拍。
歌曲弹奏如下:
123455318864553
2、当为手动按键输入的方式时,波形如下:
说明:
由图可知,此时CLK2,COUNTO,COUNT的值都变为0,因为我们要求的是手动弹奏,所以此时自动播放便没有任何意义,输出端口INDEX0只和输入INDEX2有关系,并且两者时序是一致的,在整个过程中,AUT0始终为高电平。
(三)发音模块的波形图:
说明:
由图可知,INDEX此时为输入端口,TONEO为每一个音符的预置分频数,跟前文的表格式相一致的,CODE是为相应得二进制形式,另外,HIGH表示是否高8度,通过图可知当弹到8即高音do时,HIGH变为高电平,表示此时高8度,而其他时候都低音。
(四)分频模块的波形图:
说明:
由图可知,音乐由时基脉冲值转化为音符的频率,T0NE1为音符的预置分
频数。
当COUNT11加1时,扬声器SPKS变为lo
(五)顶层文件波形图:
说明:
由图可知此时的ANDTIAUTO也是控制自动演奏的,C
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VHDL 语言 设计 简易 电子琴 演奏