基于FPGA的简单音乐电路设计剖析.docx
《基于FPGA的简单音乐电路设计剖析.docx》由会员分享,可在线阅读,更多相关《基于FPGA的简单音乐电路设计剖析.docx(24页珍藏版)》请在冰豆网上搜索。
基于FPGA的简单音乐电路设计剖析
第9章基于FPGA的简单音乐电路设计
☞ 要求
理解运用VHDL硬件描述语言和QuartusII开发工具进行音乐电路设计的方法
知识点
●理解音乐电路总体方案设计方法
●理解音乐电路各模块设计方法
重点和难点
●理解音乐电路各模块设计方法
引言
音乐电路广泛用于自动答录装置、手机铃声、集团电话及智能仪器仪表设备中。
随着CPLD/FPGA集成度的提高,价格下降,EDA设计工具更新换代,功能日益强大,以CPLD/FPGA实现乐曲演奏电路会越来越多。
本章将引导学生应用VHDL语言设计一个音乐电路。
9.1工作任务的陈述与背景
一、工作任务的陈述
使用层次化设计方法,设计并用FPGA实现一个能循环播放乐曲的音乐电路。
二、工作任务的背景
据有关媒体介绍,中国的第一颗人造卫星东方红一号卫星,于1965年开始研制,1970年4月24日进入太空轨道,该星重量超过了苏、美、法、日等前4个国家第一颗卫星重量的总和,在某些技术方面超过上述4个国家第一颗卫星的水平,开创了中国航天史的新纪元。
东方红一号重173公斤,设计寿命为14天,实际寿命达到20天,1970年5月14日停止发送信号。
关键技术包括《东方红》乐音装置、短波天线遥测系统等4项。
其中电子乐音发生器是全星的核心部分,它通过20兆赫兹短波发射系统反复向地面播送“东方红”乐曲的前八小节,全中国人民乃至全世界的人民通过收音机都能听得到。
完成研制东方红乐音装置任务的是中国科学院自动化所的一个小组。
他们首先考虑,用什么样的方法来模拟出“东方红”乐曲。
当时有三种方案提上了台面,一种是八音盒方案,它采用机械齿轮播放音乐;另一种就是把音乐录在磁带机上,但是当时中国还没有小磁带机,都是笨重的大磁带机,不可能装上卫星升空;因此第三种方案自然就是电子音乐,这也是后来被广泛接受的一种方案。
根据上级要求,只需让卫星播放《东方红》前八个小节的旋律。
小组决定在四十秒内连续播放两遍这八个小节,然后发射机就切换成遥测信号,用一个发射机就可以实现交替传送乐曲和遥测信号的目的。
这是国内早期最知名,影响最大的一个音乐电路。
在国内缺乏集成电路,没有微处理器的那个时代,东方红乐音装置全部用晶体管分立元件做成。
有人粗略统计,整个乐音装置全部共用了110多个晶体三极管(绝大多数是3DG6),大约150个二极管(都是2AP10),其他都是电阻电容。
现在,音乐电路广泛用于自动答录装置、手机铃声、集团电话及智能仪器仪表设备中。
作为一个电子系统的一个模块,音乐电路的实现方法有以下几种:
(1)购买专用音乐电路片。
特点是价格便宜,多用于玩具,无法更改乐曲,也无法编程。
(2)录音重放电路,如ISD系列录放电路。
可通过麦克风人工录音,分段放音,成本稍高。
(3)利用微处理器来实现乐曲演奏,需要占用微处理器的资源较多(要占用D/A和定时器等),大多数情况无法采用这种方法。
(4)以CPLD/FPGA实现乐曲演奏,也就是本任务要求使用的方法。
用这种方法实现音乐电路,现在单独价格较高。
但随着CPLD/FPGA集成度的提高,价格下降,EDA设计工具更新换代,功能日益强大,操作方便实用,以及IPcore概念日益普及与流行,使这种方案的应用领域会越来越多。
它的突出优点是:
第一,仅占用FPGA中很少的资源,因此增加的系统整体成本较低,甚至不增加成本。
这是因为某个产品选定某型号FPGA芯片,产品的其它部分只用了其中一部分资源,还有相当一部分资源闲置没用;第二,更改乐曲非常方便;第三,可作为IPcore实现设计重用。
9.2完成工作任务的引导
一、资讯
1.明确任务
作为初步的开发设计,为了简化设计,本任务设计的音乐电路可只考虑音的最重要的两个方面:
“音的高低”和“音的长短”,即音高和音长,忽略音的力度和音色。
要求音乐电路最少能连续循环演奏一首歌曲或一首歌曲的一部分,在此基础上可再做进一步的扩展。
由于不考虑音色,考虑到充分利用FPGA的数字电路资源,可用一个可控分频电路模块产生演奏音乐所需的每个音,而各个音演奏的顺序和持续的时间即音长可根据乐谱用一个控制电路模块来控制。
电路输入是两路时钟信号:
一路作为可控分频电路模块的输入时钟,经可控分频电路模块分频后,得到各种所需的乐音信号。
一路作为控制电路模块的输入时钟,用来产生节拍。
这两路时钟信号的频率根据具体的实验条件和所选歌曲可有所不同。
电路的输出有:
一路一线是乐音信号输出,用来驱动外接喇叭或蜂鸣器演奏音乐。
一路一线用来驱动外接的一个LED,演奏高音时发光。
一路四线用来驱动外接的数码管显示演奏的音符简谱符号。
2.查阅资料
到图书馆、互联网查找有关资料。
前人发表的有关音乐电路的文章主要散见在学术期刊和有关网页上。
可用乐曲演奏电路、音乐发生器等关键词查找。
另外,要理解这些文章所介绍的原理,还要具有音乐简谱、乐音频率的有关知识,如果缺乏,可再查找有关音乐简谱、乐音频率的知识。
本章第三节,提供了一些与本任务有关的资料,请认真阅读。
二、计划
音乐电路是模仿人歌唱的电路。
故可用人歌唱作为原型来分析设计本任务的总体方案。
人通过声带振动发出声音,声带振动频率不同发出不同声音。
故在用数字电路来模仿时,可用一个可控分频电路来产生不同频率时钟信号来用来驱动外接喇叭或蜂鸣器演奏音乐。
人在歌唱时,是根据歌谱,用大脑控制声带按照一定节拍来在不同时间发出不同的乐音的。
故在用数字电路来模仿时,还应该有一个控制电路模块,用来根据歌谱控制可控分频电路模块按照一定节拍来在不同时间发出不同的乐音的。
而控制电路模块应该分为两个小模块,一个用来产生节拍,称节拍产生模块。
另一个用来根据歌谱控制可控分频电路模块在不同时间发出不同的乐音,称音符产生模块。
控制电路模块只是根据歌谱产生可供控制可控分频模块,按照一定节拍来在不同时间发出不同的乐音的音符信号。
具体要控制可控分频模块,还得要把音符信号转换为可控分频模块的分频系数输入信号,另外也要根据音符信号决定提供给外围数码管的用于显示简谱音符符号的数据和提供给外围LED的用于显示高低音的数据。
这就需要另一个模块:
分频系数、LED数据产生模块了。
由于音乐电路是连续循环演奏,故控制电路模块的核心部分——节拍产生模块应是一个计数器,每个状态持续的时间是需演奏的所有的音的音长的最小公因数,比如是一个十六分音符时值,具体时间长度应根据需演奏歌曲而定。
这样,每个音持续的时间是每个状态持续的时间的整数倍,故占据整数倍个状态。
具体占据状态的个数要根据每个音的音长来决定。
控制电路的计数器的模即状态数,可由需演奏歌曲的各个音所占据状态个数累加而得。
例如一首用于演奏“梁祝”乐曲的音乐电路的控制电路的计数器的模是139。
节拍产生电路的计数器,用来产生节拍定时,音符产生模块则将节拍产生电路的计数器的状态翻译成对应的音符,假如需演奏的歌曲中所用到的音符在9到16个之间,则音符产生模块的输出信号应有四位,其它情况,依此类推。
分频系数、LED数据产生模块则根据音符产生模块输出的音符信息,产生每个时刻提供给可控分频模块的分频系数、提供给外围数码管的用于显示简谱音符符号的数据和提供给外围LED的用于显示高低音的数据。
因此,音乐电路设计总体参考方案如下:
图9-1音乐电路设计总体参考方案
其中的两个时钟频率取值,下面再做分析。
三、决策
本音乐电路设计重点在可控分频模块和控制电路模块的设计,故只讨论这两个模块以及顶层模块的设计方案的选择。
1.可控分频模块设计方案的选择
(1)等占空比和非等占空比方案选择
可控分频电路按输出时钟的占空比来分,有等占空比和非等占空比两类方案,为了得到足够功率驱动蜂鸣器,采用等占空比输出的可控分频电路方案。
(2)偶数分频、整数分频方案的选择
常见的分频电路有偶数分频、奇数分频和整数分频电路,本任务从原理来看,既有偶数分频又有奇数分频,故应属于整数分频电路。
非等占空比的偶数分频、奇数分频电路有统一的设计方法并且比较简单,但等占空比的偶数分频、奇数分频电路设计方法则不相同。
对于偶数(2N)的等占空比分频,可先做N非等占空比分频,再做2分频即可,比较简单。
对于等占空比的奇数分频电路则不能采用这种方法,比较复杂。
本任务可采取用较高频率(比如12MHz)的输入时钟,这样分频比就比较大,故对于初学者,作为初步解决方案,可采用偶数分频比近似代替奇数分频比的方法,把整数分频电路变成偶数(2N)分频电路,用先做N非等占空比分频,再做2分频这种较简单的方法来设计。
作为提高,可采用比较复杂的真正的整数分频电路设计方法设计。
2.控制电路模块设计方案的选择
控制电路模块的核心部分——节拍产生模块是一个计数器,可采用通常的方法设计。
音符产生模块的输入信号是节拍产生模块输出的计数值,输出信号是表示音符的音符序号。
在节拍产生模块输出的计数值变化范围不大并且音符产生模块的输出数值不需灵活改变时,可用VHDL语句直接来描述音符产生模块即可。
在节拍产生模块输出的计数值变化范围较大或音符产生模块的输出数值需灵活改变时,可使用LPM_ROM来存储对应于不同计数值的音符序号。
3.VHDL输入设计法和原理图输入设计法的选择
本任务,底层模块采用VHDL输入设计法较简单,而顶层模块采用VHDL输入设计法或原理图输入设计法都可。
四、实施
下面用用于演奏“梁祝”乐曲的音乐电路为例,对音乐电路各模块的实施进行进一步的分析。
(一)控制电路模块
控制电路模块包含节拍产生模块和音符产生模块两子模块,可合写成一个文件。
1.节拍产生模块设计分析
根据以上分析,此模块为一计数器,现在需进一步决定计数器的模及其输入时钟频率。
根据乐曲“梁祝”的简谱,此乐曲以四分音符为一拍,四拍为一节,所有的音的音长的最小公因数是一个十六分音符时值,所以以十六分音符时值作为一个状态持续时间,把乐曲“梁祝”中各个音所占据状态个数累加而得知节拍产生模块计数器的模是139,其中最后休止符用了三个时间单位。
乐曲“梁祝”的简谱没有明确标出演奏速度,根据经验设定一分钟演奏60拍,因此一拍持续时间即四分音符的时值为一秒,一个状态持续时间即一个十六分音符时值为0.25秒。
故节拍产生模块输入时钟周期为0.25秒,频率为4Hz。
2.音符产生模块设计分析
音符产生模块的功能是将节拍产生电路的计数器的计数值按照乐曲“梁祝”的简谱翻译成对应的音符,若用Counter表示计数器的状态,Index表示音符符号,可把乐曲“梁祝”的简谱出现的音规定如下:
表9-1音符与Index、LED数据的对应关系
低音
中音
高音
音名
1
2
3
4
5
6
7
1
2
3
4
5
6
7
1
Index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
那么,根据乐曲“梁祝”的简谱可得其真值表如下:
表9-2音符产生模块真值表
Counter:
Index
Counter:
Index
Counter:
Index
Counter:
Index
Counter:
Index
00:
3;
01:
3;
02:
3;
03:
3;
04:
5;
05:
5;
06:
5;
07:
6;
08:
8;
09:
8;
10:
8;
11:
9;
12:
6;
13:
8;
14:
5;
15:
5;
16:
12;
17:
12;
18:
12;
19:
15;
20:
13;
21:
12;
22:
10;
23:
12;
24:
9;
25:
9;
26:
9;
27:
9;
28:
9;
29:
9;
30:
9;
31:
9;
32:
9;
33:
9;
34:
9;
35:
10;
36:
7;
37:
7;
38:
6;
39:
6;
40:
5;
41:
5;
42:
5;
43:
6;
44:
8;
45:
8;
46:
9;
47:
9;
48:
3;
49:
3;
50:
8;
51:
8;
52:
6;
53:
5;
54:
6;
55:
8;
56:
5;
57:
5;
58:
5;
59:
5;
60:
5;
61:
5;
62:
5;
63:
5;
64:
10;
65:
10;
66:
10;
67:
12;
68:
7;
69:
7;
70:
9;
71:
9;
72:
6;
73:
8;
74:
5;
75:
5;
76:
5;
77:
5;
78:
5;
79:
5;
80:
3;
81:
5;
82:
3;
83:
3;
84:
5;
85:
6;
86:
7;
87:
9;
88:
6;
89:
6;
90:
6;
91:
6;
92:
6;
93:
6;
94:
5;
95:
6;
96:
8;
97:
8;
98:
8;
99:
9;
100:
12;
101:
12;
102:
12;
103:
10;
104:
9;
105:
9;
106:
10;
107:
9;
108:
8;
109:
8;
110:
6;
111:
5;
112:
3;
113:
3;
114:
3;
115:
3;
116:
8;
117:
8;
118:
8;
119:
8;
120:
6;
121:
8;
122:
6;
123:
5;
124:
3;
125:
5;
126:
6;
127:
8;
128:
5;
129:
5;
130:
5;
131:
5;
132:
5;
133:
5;
134:
5;
135:
5;
136:
0;
137:
0;
138:
0;
3.设计文件实体描述
两模块可合起来写成一个文件NoteTabs.vhd,其实体描述如下:
LIBRARYieee;
USEieee.std_logic_1164.ALL;
ENTITYNoteTabsIS
PORT(clk:
INSTD_LOGIC;
Index:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
END;
其中输入时钟信号与Clk4Hz相连,Index表示音符信息。
因为Index取值从1到15,故为4位二进制信号。
其结构体设计可参考例9.3。
(二)分频系数、LED数据产生模块
1.设计文件实体描述
此模块的功能是产生提供给可控分频模块的分频系数、提供给外围数码管和外围LED的数据。
其实体描述如下:
LIBRARYieee;
USEieee.STD_LOGIC_1164.ALL;
ENTITYToneTabaIS
PORT(Index:
INSTD_LOGIC_VECTOR(3DOWNTO0);
Seg:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
Led:
OUTSTD_LOGIC;
Tone:
OUTSTD_LOGIC_VECTOR(10DOWNTO0));
END;
其中Index为4位二进制信号,表示音符的信息,Seg为4位二进制信号,是提供给外围数码管的用于显示简谱音符符号的数据,Led是提供给外围LED的用于显示高低音的数据。
Tone是供给可控分频模块的分频系数。
它们的关系如表9-3所示。
2.结构体设计分析
乐曲“梁祝”是F调,其频率数据如表9-3所示。
在表中,可控分频模块的输入时钟设为12MHz,经前后12×2分频后为500000Hz,故供给可控分频模块的分频系数Tone=211-500000/f。
又考虑到最大分频比为500000/349.2≈1432,其二进制表示是10110011000,故可控分频模块的计数器为11位二进制计数器。
表9-3分频系数、LED数据产生模块真值表
F调
简谱
音名
Index
Seg
Led
频率f
Tone
Tone(B)
低音
1
f1
1
0001
0
349.2
616
01001101000
2
g1
2
0010
0
392.0
773
01100000101
3
a1
3
0011
0
440.0
912
01110010000
4
b1b
4
0100
0
466.2
976
01111010000
5
c2
5
0101
0
523.3
1092
10001000100
6
d2
6
0110
0
587.3
1197
10010101101
7
e2
7
0111
0
659.3
1290
10100001010
中音
1
f2
8
0001
1
698.5
1372
10101011100
2
g2
9
0010
1
784.0
1410
10110000010
3
a2
10
0011
1
880.0
1480
10111001000
4
b2b
11
0100
1
932.3
1512
10111101000
5
c3
12
0101
1
1047
1570
11000100010
6
d3
13
0110
1
1175
1622
11001010110
7
e3
14
0111
1
1319
1668
11010000100
高音
1
f3
15
0001
1
1397
1690
11010011010
这是一个简单的组合逻辑模块,其VHDL描述比较简单,这里不再介绍。
(三)可控分频模块
此模块的功能是用一个可控分频电路来产生演奏音乐所需的每个音。
可控分频模块实体描述如下:
LIBRARYieee;
USEieee.std_logic_1164.ALL;
USEIEEE.std_logic_unsigned.ALL;
ENTITYSpeakeraIS
PORT(clk:
INSTD_LOGIC;
Tone:
INSTD_LOGIC_VECTOR(10DOWNTO0);
SpkS:
OUTSTD_LOGIC);
END;
作为初步解决方案,采用偶数分频比近似代替奇数分频比的方法,把整数分频电路变成偶数分频电路来设计。
可控分频模块是一个具有12预分频和2后分频的可控分频电路。
可控分频模块的输入时钟clk频率选12MHz,为了使可控分频模块分频系数取值范围比较合适,输入时钟先经12分频,同时为了使输出信号SpkS具有较高的驱动功率,可控分频后再经2分频,使输出信号SpkS具有50%的占空比,从而具有较高的驱动功率。
可控分频模块的输入时钟为12MHz,经前后12×2分频后为500000Hz,应根据此频率来计算各音的分频系数,计算中对小数四舍五入。
这相当于把整数分频电路变成偶数(2N)分频电路,用先做N非等占空比分频,再做2分频这种较简单的方法来设计。
根据最大分频比的二进制表示的位数来确定可控分频电路的计数器的位数。
例如乐曲“梁祝”,最大分频比为500000/349.2≈1432,其二进制表示是10110011000,故可控分频模块的计数器为11位二进制计数器。
分频电路的描述与计数器电路相似,下面进程描述一个12分频电路。
PROCESS(clk)
VARIABLECount4:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PreCLK<='0';--将CLK进行12分频,PreCLK为CLK的12分频
IFCount4>11THENPreCLK<='1';Count4:
="0000";
ELSIFclk'EVENTANDclk='1'THENCount4:
=Count4+1;
ENDIF;
ENDPROCESS;
可控分频模块结构体中其他部分代码如可控分频电路进程和后两分频电路进程的描述可参考例9.2。
(四)顶层模块
顶层模块的功能是把以上各个模块组装起来构成一个完整的电路。
顶层模块可用VHDL输入法设计,也可用原理图输入法设计。
下面是根据音乐电路的总体方案设计,得到的的顶层模块的VHDL参考设计描述。
LIBRARYieee;
USEieee.STD_LOGIC_1164.ALL;
ENTITYSongerIS
PORT(Clk12MHZ:
INSTD_LOGIC;
Clk4HZ:
INSTD_LOGIC;
SegCode:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
LedHigh:
OUTSTD_LOGIC;
SpkOut:
OUTSTD_LOGIC);
END;
ARCHITECTUREoneOFSongerIS
COMPONENTNoteTabs
PORT(clk:
INSTD_LOGIC;
Index:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDCOMPONENT;
COMPONENTToneTaba
PORT(Index:
INSTD_LOGIC_VECTOR(3DOWNTO0);
Seg:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
Led:
OUTSTD_LOGIC;
Tone:
OUTSTD_LOGIC_VECTOR(10DOWNTO0));
ENDCOMPONENT;
COMPONENTSpeakera
PORT(clk:
INSTD_LOGIC;
Tone:
INSTD_LOGIC_VECTOR(10DOWNTO0);
SpkS:
OUTSTD_LOGIC);
ENDCOMPONENT;
SIGNALTone:
STD_LOGIC_VECTOR(10DOWNTO0);
SIGNALToneIndex:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
u1:
NoteTabsPORTMAP(clk=>CLK4HZ,Index=>ToneIndex);
u2:
ToneTabaPORTMAP(Index=>ToneIndex,Seg=>SegCode,Led=>LedHigh,
Tone=>Tone);
u3:
SpeakeraPORTMAP(clk=>Clk12MHZ,Tone=>Tone,SpkS=>SpkOut);
END;
五、检查
分别编译各底层模块和整个电路设计,并分别仿真控制电路模块和分频系数、LED数据产生模块。
通过后,若有条件,应将源代码下载到硬件中做最后的验证。
六、评估
对本次设计进行评估,可尝试更好的方案、方法。
写出设计报告,设计报告应包括所应用