课程设计论文基于vhdl的简易乐曲演奏器的设计.docx
- 文档编号:9022013
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:28
- 大小:176.13KB
课程设计论文基于vhdl的简易乐曲演奏器的设计.docx
《课程设计论文基于vhdl的简易乐曲演奏器的设计.docx》由会员分享,可在线阅读,更多相关《课程设计论文基于vhdl的简易乐曲演奏器的设计.docx(28页珍藏版)》请在冰豆网上搜索。
课程设计论文基于vhdl的简易乐曲演奏器的设计
1引言
VHDL是一种硬件描述语言,它可以对电子电路和系统的行为进行描述,基于这种描述,结合相关的软件工具,可以得到所期望的实际电路与系统。
使用VHDL语言描述的电路,可以进行综合和仿真。
然而,值得注意的是,尽管所有VHDL代码都是可仿真的,但并不是所有代码都能综合。
VHDL被广泛使用的基本原因在于它是一种标准语言,是与工具和工艺无关的,从而可以方便地进行移植和重用。
VHDL两个最直接的应用领域是可编程逻辑器件(PLD)和专用集成电路(ASIC),其中可编程逻辑器件包括复杂可编程逻辑器件(CPLD)和现场可编程门阵列(FPGA)。
关于VHDL最后要说明的是:
与常规的顺序执行的计算机程序不同,VHDL从根本上讲是并发执行的。
在VHDL中,只有在进程(PROCESS)、函数(FUNCTION)和过程(PROCEDURE)内部的语句才是顺序执行的。
本课程设计主要是基于VHDL文本输入法设计乐曲演奏电路,该系统基于计算机中时钟分频器的原理,采用自顶向下的设计方法来实现,通过按键输入来控制音响或者自动演奏已存入的歌曲。
系统实现是用硬件描述语言VHDL按模块化方式进行设计,然后进行编程、时序仿真、电路功能验证,奏出美妙的乐曲(当然由于条件限制,暂不进行功能验证,只进行编程和时序仿真)。
该设计最重要的一点就是通过按键控制不同的音调发生,每一个音调对应不同的频率,从而输出对应频率的声音。
我们知道,与利用单片机来实现乐曲演奏相比,以纯硬件完成乐曲演奏电路的逻辑要复杂得多,如果不借助于功能强大的EDA工具与硬件描述语言,仅凭传统的数字逻辑技术,即使最简单的演奏电路也难以实现。
2整体功能介绍
2.1准备知识
在本次设计中采用了铃声《北京欢迎你》作为要播放的乐曲,它的旋律如下:
35323233261322
216123523656211
2161235236553-
232156253323(加粗表示低音,其他为中音)
根据声乐知识,组成乐曲的每个音符的发音频率值及其持续的时间是乐曲能连续演奏所需的两个基本要素,获取这两个要素所对应的数值以及通过纯硬件的手段来利用这些数值实现所希望乐曲的演奏效果是本实验的关键。
表2-1为简谱中音名与频率的对应关系。
音名
频率(Hz)
音名
频率(Hz)
音名
频率(Hz)
低音1
261.63
中音1
523.25
高音1
1046.50
低音2
293.67
中音2
587.33
高音2
1174.66
低音3
329.63
中音3
659.25
高音3
1381.51
低音4
349.23
中音4
698.46
高音4
1396.92
低音5
391.99
中音5
783.99
高音5
1567.98
低音6
440
中音6
880
高音6
1760
低音7
439.88
中音7
987.76
高音7
1975.52
表2-1音名和频率的关系
1.基准频率的选取
各音名所对应的频率可由一频率较高的基准频率进行整数分频得到,所以实际产生各音名频率为近似的整数值。
这是由于音阶频率多为非整数,而分频系数又不能为小数,故必须将得到的分频系数四舍五入取整,若基准频率过低,则由于分频系数过小,四舍五入取整后的误差较大,若基准频率过高,虽然误码差较小,但分频结构将变大,实际的设计应综合考虑两方面的因素,在尽量减小频率差的前提下取舍合适的基准频率。
本次设计选择12MHz作为基准频率。
2.分频系数A、公用二进制的计数容量N及初始值的选取D
(1)分频系数的选取
首先将12MHz的基准频率进行12分频,得到1MHz的基准频率,分频系数A=1MHz/音名频率,此分频系数可由计数器实现。
但若不加处理语句,其分频后的信号将不是对称方波。
而占空比很小的方波很难使扬声器有效地发出声响。
为得到对称方波,可将分频系数A分解为:
分频系数A=分频系数n×2。
即先进行分频系数n的分频,得到不对称方波,然后再2分频得到对称方波。
(2)公用二进制的计数容量N的选取
n分频可由n进制计数器实现。
n进制计数器可用复位法或置位法实现,由于加载初始值d的置位法可有效地减少设计所占用的可编程逻辑器件资源,因此,此次设计采用置位法。
低音1的分频数n为最大,其值为1275,应取公用二进制计数器的计数容量N大与“最大分频系数n”,故本次设计的公用二进制计数器应该设计为十一位二进制加法计数器,其计数最大容量为2048,计数的最大值N为2047,可满足本次设计中所有音名对音频系数的要求。
3.初始值的选取D
初始值D=计数最大值N-分频系数n
此次设计中应用的各音名对应的分频系数值及初始值如表2-2所示:
由于对应的频率点都有小数部分,在分频时不需花大量时间去产生分频电路,只要大概频率点在此范围内即可,本实验采用频率点及音符与音谱对应定义如表2-2所示。
音符
对应频率点
对应音谱
区别高中低音
5
771
5
0
6
911
6
0
1
1091
1
1
2
1196
2
1
3
1289
3
1
4
1331
4
1
5
1409
5
1
6
1479
6
1
7
1541
7
1
表2-2音符和音谱等关系
该演奏电路的最小节拍为1拍,将一拍的时长定为0.25s,则只需要再提供一个4Hz的时钟频率即可产生一拍的时长。
为了能达到演奏时能循环进行,则需设置一个时长计数器,当乐曲演奏完时,保证能自动从头开始演奏。
因采用4HZ的频率,故将音谱修改为
33553322332233333322
66113322222211661122
33552233665566221111
22116611223355223366
55553333333322332211
556622225533333322223333
2.2乐曲演奏电路的结构示意
本设计由5个模块组成,顶层结构所包含的模块分别为分频器(fenpin)模块、音调发生器(ydfsq)模块、音调编码器(ydbmq)模块、手动\自动选择(bmux)模块及数控分频器(skfpq)模块。
如图2-3所示
分频器
图2-3电路结构示意图
2.3整体功能描述
演奏时可以通过按键选择是手动演奏还是自动演奏,自动演奏则是演奏已存入的固定乐曲,而且自动播放能重复播放;手动演奏是通过按键进行简易乐曲的演奏;进行手动演奏和自动演奏时,数码管上要同时能显示出演奏乐曲的乐谱。
3各模块及顶层介绍及仿真
3.1分频器
功能描述
根据设计要求,需要用一个时钟信号对音调发生模块和音调编码模块进行控制,该模块是将12MHZ的频率分成4HZ,以便用于产生音调发生器的CLK。
源程序如下:
libraryieee;
u
entityfpqis
port(clk:
instd_logic;
out1:
bufferstd_logic);
endfpq;
architecturebhvoffpqis
begin
process(clk)
variablecount:
integerrange0to1500000;
begin
Ifclk'eventandclk='1'then
count:
=count+1;
Ifcount=1500000then
out1<=notout1;
count:
=0;
endif;endif;endprocess;endbhv;
仿真图
图3-1分频器仿真图
3.2音调发生器
功能描述
在此模块中设置了一个计数器(计数最大值为200),这个计数器的计数频率选为4Hz,即每一计数值的停留时间为0.25s,恰好为当全音符设为1s时,四四拍的4分音符的持续时间。
例如,ydfsq在以下的VHDL逻辑描述中,“北京欢迎你”乐曲的第一个音符为“3”,此音在逻辑中停留了2个时钟节拍,即为0.5s时间,相应地所对应“3”音符分频预置数为1289在skfpq的输入端停留了0.5s。
随着计数器按4Hz的时钟频率做加法计数时,乐谱逐次被选取,乐曲就开始自然连续而且循环地演奏起来。
源程序如下:
libraryieee;
库的声明
entityydfsqis
port(clk:
instd_logic;
toneindex:
outintegerrange0to15);
end;
architecturebhvofydfsqis
signalcounter:
integerrange0to200;--读取音符谱中的音符
begin
process(clk,counter)
begin
ifcounter=63then
counter<=0;
elsifclk'eventandclk='1'then
counter<=counter+1;
endif;
endprocess;
process(counter)
begin
casecounteris
when108|109=>toneindex<=5;
when20|21|34|35|52|53|64|65=>toneindex<=6;
when22|23|32|33|36|37|56to59|62|63|66|67|98|99=>toneindex<=8;
when6|7|10|11|18|19|26to31|38|39|44|45|54|55|60|61|68|69|74|75|92|93|96|97|104to107|116to119=>toneindex<=9;
When0|1|4|5|8|9|12to17|24|25|40|41|46|47|70|71|76|77|84to91|94|95|110to115|120to123=>toneindex<=10;
When2|3|42|43|50|51|72|73|80to83|100|101|108|109=>toneindex<=12;
When78|79|102|103=>toneindex<=13;
Whenothers=>null;
endcase;
endprocess;
end;
仿真图
图3-2音调发生器仿真图
通过仿真图可以清楚的看到,时钟clk由0开始计数,每计一次数输出toneindex的值随之发生一定的变化,只不过根据乐谱的不同,输出的变化也不尽相同。
然后把输出toneindex输入到音调编码器模块,进行下一步编码工作。
于是,由仿真图印证了ydfsq模块逐次选取音符的功能。
3.3手动自动选择器
功能描述
根据设计的要求,该简易乐曲演奏器能实现手动或自动演奏乐曲的功能。
于是,可通过一个按键cs来进行自动与手动的选择,当cs按下时,乐曲自动演奏,其他情况下均为手动演奏乐曲,即可以通过按下其他的按键来控制不同的音符。
与此同时,还需要一个复位信号rst来控制该演奏器是否工作,当rst为1时,停止演奏,为0时可以演奏。
以上提到的手动与自动的选择只能在rst为0时有效。
源程序如下:
libraryieee;
entitybmuxis
port(d1,d2:
inintegerrange0to15;
cs,rst:
instd_logic;
q:
outintegerrange0to15);
end;
architecturebhvofbmuxis
begin
process(cs,rst)
begin
ifrst='1'then
q<=0;
else
casecsis
when'0'=>q<=d1;
when'1'=>q<=d2;
whenothers=>q<=d1;
endcase;
endif;
endprocess;
end;
3.3.2仿真图
图3-3手动/自动选择器仿真图
此仿真图中输入cs代表手动\自动演奏的选择端,输入rst代表整体复位端,输入d1、d2分别代表手动和自动演奏的音符,q为输出端,由此仿真图可清楚的看到当rst=1时,不论选择的是手动还是自动,输出都为零,达到了整体复位的功能;当rst=0且cs=1时,自动演奏乐曲,因为q与d2的值相同;当rst=0且cs=0时,手动演奏乐曲,因为这时的q与d1的值相同,从而也达到了演奏方式选择的功能
3.4音调编码器
功能描述
该编码模块的作用为将输入的音符数据翻译为音乐产生模块的所需要的分频系数,并且显示音符的数字码型和高音阶,通过对照表2-2各音名对应的分频系数值及初始值,根据输入得到初始值,从而得到分频系数以便进行分频,得到所需的频率。
源程序如下:
libraryieee;
entityydbmqis
port(index:
inintegerrange0to15;
code:
outintegerrange0to15;
code1:
outintegerrange0to15;
tone:
outintegerrange0to2047);
end;
architecturebhvofydbmqis
begin
process(index)
begin
caseindexis
when5=>tone<=771;code<=5;code1<=0;when6=>tone<=911;code<=6;code1<=0;
when8=>tone<=1091;code<=1;code1<=1;when9=>tone<=1196;code<=2;code1<=1;
when10=>tone<=1289;code<=3;code1<=1;when11=>tone<=1331;code<=4;code1<=1;
when12=>tone<=1409;code<=5;code1<=1;when13=>tone<=1479;code<=6;code1<=1;
when14=>tone<=1541;code<=7;code1<=1;
whenothers=>NULL;
endcase;
endprocess;
end;
3.4.2仿真图
图3-4音调编码器仿真图
在此程序中index为音乐节拍产生模块输出的音符数据,经过翻译后将tone输出到数控分频模块为其提供分频系数的初始值,code为数码管显示的字符数,应用模式5,所以直接输出音符的二进制值,code1为高音阶指示信号,当code1为1是说明输出为高音阶的音符。
通过仿真图可以清楚地看到结果。
3.5数控分频器
功能描述
该模块的clk端输入一个具有较高频率(本实验为12MHz)的信号,通过skfpq分频后由spkout输出。
由于直接从数控分频器中出来的输出信号是脉宽极窄的脉冲信号,为了便于驱动喇叭,需另加一个D触发器均衡其占空比,也即作二分频处理。
skfpq对clk输入信号的分频比由11位预置数tone[10..0]决定。
spkout的输出频率将决定每一音符的音调,这样分频计数器的预置数tone[10..0]与spkout的输出频率就有了对应关系。
源程序如下:
libraryieee;
entityskfpqis
port(clk:
instd_logic;
tone:
inintegerrange0to2047;
spks:
outstd_logic);
end;
architecturebhvofskfpqis
signalpreclk:
std_logic;
signalfullspks:
std_logic;
begin
process(clk)
variablecount4:
integerrange0to15;
begin
preclk<='0';
ifcount4=12then--将基准频率进行12分频
preclk<='1';count4:
=0;
elsifclk'eventandclk='1'then
count4:
=count4+1;
endif;
endprocess;
process(preclk,tone)
variablecount11:
integerrange0to2047;
begin
ifpreclk'eventandpreclk='1'then--按分频系数进行分频
ifcount11=2047then
count11:
=tone;fullspks<='1';
else
count11:
=count11+1;fullspks<='0';
endif;
endif;
endprocess;
process(fullspks)
variablecount2:
std_logic;
begin
iffullspks'eventandfullspks='1'then
count2:
=notcount2;
ifcount2='1'then
spks<='1';
else
spks<='0';
endif;endif;endprocess;end;
3.5.2仿真图
图3-5数控分频器仿真图
在此仿真图中,输入clk是一个频率较大的时钟信号,输入tone代表着某个音符的分频初始值,输出spks则代表将输入clk先经过12次分频,再经过(预置数终值2048-tone)次分频,最终再进行二分频处理,而这个信号的频率就是我们需要演奏的音谱的频率,根据频率的不同,从而能通过喇叭听到不同的声音,实现音乐的播放。
3.6系统顶层
源程序
libraryieee;
entitybfqis
port(clk1:
instd_logic;
CS:
instd_logic;
RST:
instd_logic;
D2:
inintegerrange0to15;
oup1:
outstd_logic;
oup2:
outintegerrange0to15;
oup3:
outintegerrange0to15);end;
architecturebhvofbfqis
signals1:
integerrange0to15;
signals2:
integerrange0to15;
signals3:
integerrange0to2047;
signals4:
std_logic;
componentfpqis
port(clk:
instd_logic;
out1:
outstd_logic);endcomponent;
componentydfsqis
port(clk:
instd_logic;
toneindex:
outintegerrange0to15);endcomponent;
componentydbmqis
port(index:
inintegerrange0to15;
code:
outintegerrange0to15;
code1:
outintegerrange0to15;
tone:
outintegerrange0to2047);endcomponent;
componentbmuxis
port(d1,d2:
inintegerrange0to15;
cs,rst:
instd_logic;
q:
outintegerrange0to15);endcomponent;
componentskfpqis
port(clk:
instd_logic;
tone:
inintegerrange0to2047;
spks:
outstd_logic);endcomponent;
begin
u0:
fpqportmap(clk1,s4);
u1:
ydfsqportmap(s4,s1);
u2:
ydbmqportmap(s2,oup2,oup3,s3);
u3:
bmuxportmap(s1,D2,CS,RST,s2);
u4:
skfpqportmap(clk1,s3,oup1);endbhv;
仿真图
图3-6顶层仿真图
4硬件调试结果
输入程序并且编译无误,并且仿真无误后,便进行引脚锁定及程序下载,在进行引脚锁定时必须对照引脚锁定图进行锁定,采用模式5其引脚锁定图如图4-1所示:
图4-1模式5实验电路结构图
根据需要,本设计采用模式5,这是因为数码管自带译码芯片,输出时只需输出数字的二进制数,因此不必直接输出数字的码型,这就方便了字符的输出。
根据模式5上所对应的引脚号查表可以得出需要锁定的引脚号码。
引脚图如下图所示:
图4-2引脚锁定图
cs键8为自动手动选择键,当cs=1时为手动,否则为自动;clk1锁定clock0的12Mhz;oup2锁定译码管8;oup3锁定译码管1;D2锁定键1到键4;oup1锁定扬声器。
引脚锁定后执行programmer下载程序至试验箱进行验证,当键8都没按下时,为手动选择模式,默认为循环播放存储的歌,当键8按下时,为手动模式,无论手动自动译码管都显示乐谱,故经验证本次设计完成的设计基本正确,但是基准时钟选取的不同演奏的效果不同。
5总结
1、本次简易乐曲演奏器的设计经过了整体分析、模块化分析、整体与模块的仿真分析这样三个步骤,硬件实现了整体复位、按键选择演奏方式、循环演奏以及数码管显示乐谱的功能。
2、在做数控分频器模块的仿真时一定要处理好时序问题。
3、本次设计可以说达到了设计要求,但尚有需要改进的地方。
随着乐谱的复杂程度加大,如果依然在音调发生器的程序中通过时钟计数来决定音符的输出,会加大编程的繁杂度,这时一个很好的解决办法就是把将要演奏的乐谱存放在人为开辟的存储空间里,这样只需要在相应地址中读出音符即可。
通过本次课程设计,从实际应用方面深刻体会了VHDL设计的优势,通过强大的EDA工具和硬件描述语言使演奏电路很易实现。
并且通过此次设计让我们把课本中的知识系统的联系起来,更加体会到模块式设计的方法所带来的方便和明了化。
通过模块式的方法,可以将复杂的总程序分成几个模块各自分工执行,独立工作互不干扰。
然后通过原理图将各个模块直接相连,或者用元件例化的方式,用VHDL语言进行描述,达到了统一化管理各个模块的作用。
通过查找资料,与同学交流增强了我们自主学习的能力;了解到了声音音谱的发生规律,信号的频率与声音的关系
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 课程设计 论文 基于 vhdl 简易 乐曲 演奏 设计