音乐硬件演奏器Word格式.docx
《音乐硬件演奏器Word格式.docx》由会员分享,可在线阅读,更多相关《音乐硬件演奏器Word格式.docx(22页珍藏版)》请在冰豆网上搜索。
c)掌握EDA的使用工具QuartusII,通过VHDL语言的编辑得出各个模块的电路内容;
d)组成乐曲的每个音符的发音频率值及其持续的时间是乐曲能连续演奏所需要的两个基本要素,运用这两个基本要素所对应的数值,通过纯硬件的手段实现乐曲的演奏效果;
e)本设计是通过内部固定的音乐内容来实现音乐的自动播放,通过本次
内容分析其优缺点。
二、总体框图
该主系统由三个模块:
tonetaba.vhd、notetabs.vhd、speakera.vhd、div.vhd、dispa.vhd组成。
①首先定制notetabs.vhd、模块中的音符数据ROM”music”。
②根据给出的乘法器逻辑原理图及其模块的VHDL描述在QuartusⅡ上完成设计。
③完成编译,综合,仿真,管教分配,编程下载。
1.对于模块NoteTabs的功能描述:
该模块的功能就是定义音符数据ROM“music”随着该模块中的计数器控制时钟频率速率作加法计数时,即地址值递增时,音符数据ROM中的音符数据。
将从ROM中通过ToneIndex[3..0]端口输向ToneTaba模块,演奏《梁祝》。
在该模块中设置了一个8位二进制计数器(计数最大值为138),作为音符数据ROM的地址发生器。
这个计数器的计数频率为4Hz,即每一计数值的停留时间为0.25秒,恰为当全音符设为1秒时,四四拍的4分音符持续时间。
2.对于模块ToneTaba,是乐曲简谱码对应的分频预置数查找表电路,其中设置了乐曲的全部音符所对应的分频置数,其中设置了“梁祝”乐曲全部音符所对应的分频预置数,共13个,每一音符的停留时间由音乐节拍和音调发生器模块NoteTabs的CLK的输入频率决定,在此为4Hz。
这13个值的输入由对应于ToneTaba的4位输入值Index[3..0]确定,而Index[3..0]的输入最多有16种可选值。
输向ToneTaba中Index[3..0]的值ToneIndex[3..0]的输出值与持续的时间由模块NoteTabs决定。
3.模块Speakera是一个数控分频器,音符的频率可由此模块获得。
由其CLK
端输入一具有较高频率(这里是12MHz)的信号,通过Speakera分频后由SPKOUT输出,由于直接从数控分频器中出来的输出信号是脉宽极窄的脉冲式信号。
为了利用驱动扬声器,需加一个D触发器以均衡其占空比,频率将是原来的1/2。
Speakera对CLK输入信号的分频比由11位预置数Tone[10..0]决定。
SPKOUT的输出频率将决定每一音符的音调,这样,分频计数器的预置值Tone[10..0]与SPKOUT的输出频率就有了对应关系。
例如在ToneTaba模块中若取出Tone[10..0]=1036,将发音符为“3”音的信号频率
4.模块div是一个分频器,用于将50MHz分成12MHz和8Hz
5.模块dispa是一个七段译码器,用于显示乐曲的简谱码。
三、选择器件
EPF10K10LC84-4芯片,模块NoteTabs,模块ToneTaba,模块Speakera
四、功能模块
1.对于模块NoteTabs
定义音符数据ROM“music”。
Music模块存放乐曲中的音符数据,它是利用LPM-ROM来实现的,将乐谱中相应的音符放在一个连续的地址上。
它首先是编写音符数据文件,将乐谱中相应的音符存放在一个连续的地址上。
因为1拍的时间定为1秒,提供的是8Hz的时钟频率(即1/4拍的整数倍),则需将这个音符存储在相应次数的连续几个地址上。
然后对音符数据进行ROM定制。
随着NoteTabs中的计数器按时钟频率速度作加法计数时,音符数据将从ROM中通过ToneIndex端口输向ToneTaba模块。
ROM中的音符数据模块(music)程序为:
WIDTH=4;
DEPTH=256;
ADDRESS_RADIX=DEC;
DATA_RADIX=DEC;
CONTENTBEGIN
00:
3;
01:
02:
03:
04:
5;
05:
06:
07:
6;
08:
8;
09:
10:
11:
9;
12:
13:
14:
15:
16:
12;
17:
18:
19:
15;
20:
13;
21:
22:
10;
23:
24:
25:
26:
27:
28:
29:
30:
31:
0;
32:
33:
34:
35:
36:
7;
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
END;
其中WIDTH=4,表示数据输出为宽为4;
DEPTH=256,表示共有256个5位数据点;
ADDRESS-RADIX=DEC,表示地址信号用十进制;
DATA-RADIX=DEC,表示输出数据是十进制数。
NoteTabs模块的程序:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYNoteTabsIS
PORT(clk:
INSTD_LOGIC;
ToneIndex:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ARCHITECTUREoneOFNoteTabsIS
COMPONENTMUSIC
PORT(address:
INSTD_LOGIC_VECTOR(7DOWNTO0);
clock:
INSTD_LOGIC;
q:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDCOMPONENT;
SIGNALCounter:
STD_LOGIC_VECTOR(7DOWNTO0);
BEGIN
CNT8:
PROCESS(clk,Counter)
BEGIN
IFCounter=138THENCounter<
="
00000000"
;
ELSIF(clk'
EVENTANDclk='
1'
)THENCounter<
=Counter+1;
ENDIF;
ENDPROCESS;
u1:
MUSICPORTMAP(address=>
Counter,q=>
ToneIndex,clock=>
clk);
该模块的波形仿真图如下
2.对于模块ToneTaba
ToneTaba是乐曲简谱码对应的分频预置数查表电路。
以下为ToneTaba的模块程序:
LIBRARYIEEE;
ENTITYToneTabaIS
PORT(Index:
INSTD_LOGIC_VECTOR(3DOWNTO0);
CODE:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
HIGH:
OUTSTD_LOGIC;
Tone:
OUTSTD_LOGIC_VECTOR(10DOWNTO0));
ARCHITECTUREoneOFToneTabaIS
Search:
PROCESS(Index)
CASEIndexIS
WHEN"
0000"
=>
Tone<
11111111111"
CODE<
HIGH<
='
0'
--2047;
0001"
01100000101"
--773;
0010"
01110010000"
--912;
0011"
10000001100"
--1036;
0101"
10010101101"
--1197;
0110"
10100001010"
--1290;
0111"
10101011100"
--1372;
1000"
10110000010"
--1410;
1001"
10111001000"
--1480;
1010"
11000000110"
--1542;
1100"
11001010110"
--1622;
1101"
11010000100"
--1668;
1111"
11011000000"
--1728;
WHENOTHERS=>
NULL;
ENDCASE;
ENDPROCESS;
3.对于Speakera模块
Speakera的模块程序
ENTITYSpeakerIS
PORT(clk:
Tone:
INSTD_LOGIC_VECTOR(10DOWNTO0);
SpkS:
OUTSTD_LOGIC);
ARCHITECTUREoneOFSpeakerIS
SIGNALPreCLK,FullSpks:
STD_LOGIC;
DivideCLK:
PROCESS(clk)
VARIABLECount4:
STD_LOGIC_VECTOR(3DOWNTO0);
PreCLK<
='
IFCount4>
11THENPreCLK<
Count4:
ELSIFclk'
EVENTANDclk='
THENCount4:
=Count4+1;
ENDIF;
GenSpkS:
PROCESS(PreCLK,Tone)
VARIABLECount11:
STD_LOGIC_VECTOR(10DOWNTO0);
IFPreCLK'
EVENTANDPreCLK='
THEN
IFCount11=16#7FF#THENCount11:
=Tone;
FullSpkS<
ELSECount11:
=Count11+1;
FullSpks<
DelaySpkS:
PROCESS(FullSpks)
VARIABLECount2:
IFFullSpks'
EVENTANDFullSpks='
THENCount2:
=NOTCount2;
IFCount2='
THENSpkS<
ELSESpkS<
4.div模块
div模块的程序
LIBRARYieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
ENTITYdivIS
PORT(
clk:
CLK12MHz,CLK8Hz:
OUTstd_logic);
ENDdiv;
ARCHITECTUREoneofdivis
begin
u1:
process(clk)
variablecnt:
integerrange0to2;
variabletmp:
std_logic;
if(clk'
eventandclk='
)then
ifcnt>
=2then
cnt:
=0;
tmp:
=nottmp;
else
=cnt+1;
endif;
CLK12MHz<
=tmp;
endprocessu1;
u2:
integerrange0to6250000;
=6249999then
CLK8Hz<
endprocessu2;
endone;
该模块波形仿真图如下
5、dispa模块
Diapa模块的程序
libraryieee;
entitydispais
port(d:
instd_logic_vector(3downto0);
outstd_logic_vector(6downto0));
enddispa;
architecturedispa_arcofdispais
begin
process(d)
casedis
when"
q<
0111111"
0000110"
1011011"
1001111"
0100"
1100110"
1101101"
1111101"
0100111"
1111111"
whenothers=>
1101111"
endcase;
endprocess;
enddispa_arc;
五.总体设计电路图
1.顶层设计的电路原理图
Songer模块就是顶层设计文件,所有的模块都由它调用。
该Songer模块的程序为:
ENTITYSONGERIS
PORT(CLK12MHZ:
CLK8HZ:
CODE1:
OUTstd_logic_vector(3downto0);
HIGH1:
OUTSTD_LOGIC;
spkout:
outstd_logic);
ENDsonger;
ARCHITECTUREoneOFSONGERIS
COMPONENTnotetabs
Port(clk:
instd_logic;
toneindex:
outSTD_LOGIC_VECTOR(3DOWNTO0));
endcomponent;
componenttonetaba
PORT(Index:
INSTD_LOGIC_VECTOR(3DOWNTO0);
CODE:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
HIGH:
Tone:
OUTSTD_LOGIC_VECTOR(10DOWNTO0));
COMPONENTSpeaker
PORT(clk:
INSTD_LOGIC_VECTOR(10DOWNTO0);
SIGNALTone:
std_logic_vector(10downto0);
SIGNALToneIndex:
std_logic_vector(3downto0);
NotetabsPORTMAP(clk=>
CLK8HZ,toneindex=>
toneindex);
u2:
TonetabaPORTMAP(Index=>
ToneIndex,Tone=>
Tone,CODE=>
CODE1,HIGH=>
HIGH1);
u3:
SpeakerPORTMAP(clk=>
CLK12MHZ,Tone=>
Tone,SpkS=>
SPKOUT);
end;
2.顶层设计的仿真结果如下:
由于本设计从仿真图上来判断设计是否成功不太直观。
最好的方法是完成下载验证通过实际电路验证,所以这里给出仿真结果有误差不是很符合实际效果。
将Songer模块设为当前文件,进行编译,编译成功:
3.电路的管脚图如下:
4、下载验证
通过选择ALTER实验箱配置方案,按照前面所述的方法进行程序配置,然后进行验证演示
仿真结果分析、总结与解释及改进方案
1、产生各音符所需的频率可用一分频器实现,由于各音符对应的频率多为非整数而分频系数又不能为小数,故必须将计算得到的分频数四舍五入取整。
若分频器时钟频率过低,则由于分频系数过小,四舍五入取整后的误差较大;
若时钟频率产生各音符所需的频率可用一分频器实现,由于各音符对应的频率多为非整数,过高,虽然误差变小,但会增加分频器的分频级数;
2、分频计数器的预置值Tone[10..0]与SPKOUT的输出频率就有了对应关系。
在动态显示乐曲演奏器的设计中,采用音符编码输出的方式,即乐曲中每一个高、中、低音音符对应着不同的编码,由编码确定对应音符的输出频率.
3、音符的持续时间需根据乐曲的速度及每个音符的节拍数来确定,TONETABA的功能首先是为SPEAKER提供决定所发音符的分频预置数,而此数在SPEAKER输入口停留的时间即为此音符的节拍值;
优点及其改进方案:
1、VHDL类型众多而且支持用户自定义类型,支持自顶而下的设计方法和多种电路的设计,设计层次较高、用于较复杂的计算时,能尽早发现存在的问题,缩短设计周期
2、与利用微处理器(CPU或MCU)来实现乐曲演奏相比,以纯硬件完成乐曲演奏电路的逻辑要复杂得多,如果不借助于功能强大的EDA工具和硬件描述语言,仅凭传统的数字逻辑技术,即使最简单的演奏电路也难以实现;
3、利用EDA技术设计的电路,具有硬件电路简捷,集成度高。
性能稳定的优点。
这种设计方法效率高,风格灵活,体现了现代电子电路设计的先进思想;
改进方案:
本实验的音乐播放属于软件的方式内置音符,可以通过改变实现方式改变音乐的产生,用按键CS来选择不同功能,第一种功能是用手动即通过按键的形式输入不同音名,第二种功能是音乐发生器,可以自动重复播放“梁祝”音乐,当CS为高电平1时,选择功能二,当CS为低电平0时,选择功能一,其改进方案的电路如下:
经验交流:
1、相对于其它计算机语言的学习,如C或汇编语言,VHDL具有明显的特点。
这不仅仅是由于VHDL作为一种硬件描述语言的学习需要了解较多的数字逻辑方面的硬件电路知识,包括目标芯片基本结构方面的知识更重要的是由于VHDL描述的对象始终是客观的电路系统。
传统的软件编程语言只能根据CPU的工作方式,以排队式指令的形式来对特定的事件