EDA期末大作业设计.docx
《EDA期末大作业设计.docx》由会员分享,可在线阅读,更多相关《EDA期末大作业设计.docx(11页珍藏版)》请在冰豆网上搜索。
EDA期末大作业设计
宁波理工学院
EDA课程设计报告
题目简易电子琴
组员王维婷(3110403128)
郑雅亿(3110403131)
专业班级电子信息工程112班
1、实验目的
1.学习利用数控分频器、键盘实验。
2.理解PS/2键盘的基本原理。
2、实验原理
本实验利用键盘的数字按键部分来控制电子琴的C调,DORA,MI,FA,SO,LA,SI,分别用0,1,2,3,4,5,6,7来进行控制。
们使用了键盘的介入来进行控制。
组成乐曲的每个音符的发音频率值及其持续的时间是乐曲能连续演奏所需的2个基本要素,首先让我们来了解音符与频率的关系。
乐曲的12平均率规定:
每2个八度音(如简谱中的中音1与高音1)之间的频率相差1倍。
在2个八度音之间,又可分为12个半音,每2个半音的频率比为。
另外,音符A(简谱中的低音6)的频率为440Hz,音符B到C之间、E到F之间为半音,其余为全音。
由此可以计算出简谱中从低音1至高音1之间每个音符的频率,如图所示。
简谱中音符与频率的关系
如图所示,为PS/2键盘的接口引脚图。
下图为PS/2键盘的通信时序图。
主系统由4个模块组成:
TOP是顶层设计文件,其内部有三个功能模块:
Tone.VHD、Speaker.VHD、enc16_4.VHD.、PS2VHDL.VHD、clkdiv10.VHD、clkdiv50.VHD以及PULSE12.VHD
模块TONE是音阶发生器,当4位发声控制输入INDEX中某一位为高电平时,则对应某一音阶的数值将从端口TONE输出,作为获得该音阶的分频预置值;同时由CODE输出对应该音阶简谱的显示数码,如‘5’,并由HIGH输出指示音阶高8度显示。
由例6-28可见,其语句结构只是类似与真值表的纯组合电路描述,其中的音阶分频预置值,如Tone<=1290是根据产生该音阶频率所对应的分频比获得的。
简易电子琴电路结构
模块SPEAKER中的主要电路是一个数控分频器,它由一个初值可预置的加法计数器构成,当模块SPEAKER由端口TONE获得一个2进制数后,将以此值为计数器的预置数,对端口CLK12MHZ输入的频率进行分频,之后由SPKOUT向扬声器输出发声。
模块NOTETABS,用于控制音乐的暂停与播放,产生节拍控制(INDEX数据存留时间)和音阶选择信号,即在NOTETABS模块放置一个乐曲曲谱真值表,由一个计数器的计数值来控制此真值表的输出,而由此计数器的计数时钟信号作为乐曲节拍控制信号,从而可以设计出一个纯硬件的乐曲自动演奏电路。
试完成此项设计,并在EDA实验系统上的FPGA目标器件中实现之。
5、实验内容:
编译适配以上4个示例文件,给出仿真波形,最后进行下载和硬件测试实验。
建议使用实验电路模式“3”,用短路帽选择“CLOCK9”的输入频率选择12MHz,此信号作为系统输入信号CLK12MHZ;CLK8HZ与clock2相接,接受4Hz频率;键盘按键0-7作为输入信号控制各音阶。
3、实验代码
enc16_4
libraryieee;
useieee.std_logic_1164.all;
entityenc16_4is
port(I:
instd_logic_vector(7downto0);--输入的待编码信号
Y:
outstd_logic_vector(3downto0));--编码输出
endenc16_4;
architectureoneofenc16_4is
SIGNALL:
STD_LOGIC_VECTOR(7DOWNTO0);
begin
Search:
PROCESS(I)
begin
CASEIIS
WHEN"01101100"=>Y<="1000";
WHEN"01110100"=>Y<="0111";
WHEN"01110011"=>Y<="0110";
WHEN"01101011"=>Y<="0101";
WHEN"01111010"=>Y<="0100";
WHEN"01110010"=>Y<="0011";
WHEN"01101001"=>Y<="0010";
WHEN"01110000"=>Y<="0001";
WHENOTHERS=>Y<="0000";
ENDCASE;
endprocess;
endone;
Tone
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
ENTITYToneIS
PORT(Index:
INSTD_LOGIC_VECTOR(3DOWNTO0);
CODE:
OUTSTD_LOGIC_VECTOR(3DOWNTO0);
HIGH:
OUTSTD_LOGIC;
Tone:
OUTSTD_LOGIC_VECTOR(10DOWNTO0));
END;
ARCHITECTUREoneOFToneIS
BEGIN
Search:
PROCESS(Index)
BEGIN
CASEIndexIS--译码电路,查表方式,控制音调的预置数
WHEN"0000"=>Tone<=CONV_STD_LOGIC_VECTOR(2047,11);
--CONV_STD_LOGIC_VECTOR(139,11);CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='0';
WHEN"0001"=>Tone<=CONV_STD_LOGIC_VECTOR(347,11);
CODE<=CONV_STD_LOGIC_VECTOR(2,4);HIGH<='0';
WHEN"0010"=>Tone<=CONV_STD_LOGIC_VECTOR(533,11);
CODE<=CONV_STD_LOGIC_VECTOR(3,4);
HIGH<='0';
WHEN"0011"=>Tone<=CONV_STD_LOGIC_VECTOR(615,11);
CODE<=CONV_STD_LOGIC_VECTOR(4,4);
HIGH<='0';
WHEN"0100"=>Tone<=CONV_STD_LOGIC_VECTOR(773,11);
CODE<=CONV_STD_LOGIC_VECTOR(5,4);
HIGH<='0';
WHEN"0101"=>Tone<=CONV_STD_LOGIC_VECTOR(912,11);
CODE<=CONV_STD_LOGIC_VECTOR(6,4);
HIGH<='0';
WHEN"0110"=>Tone<=CONV_STD_LOGIC_VECTOR(1036,11);
CODE<=CONV_STD_LOGIC_VECTOR(7,4);
HIGH<='0';
WHEN"0111"=>Tone<=CONV_STD_LOGIC_VECTOR(1092,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHEN"1000"=>Tone<=CONV_STD_LOGIC_VECTOR(1197,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHEN"1001"=>Tone<=CONV_STD_LOGIC_VECTOR(1290,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHEN"1010"=>Tone<=CONV_STD_LOGIC_VECTOR(1372,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHEN"1011"=>Tone<=CONV_STD_LOGIC_VECTOR(1410,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHEN"1100"=>Tone<=CONV_STD_LOGIC_VECTOR(1480,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHEN"1101"=>Tone<=CONV_STD_LOGIC_VECTOR(1542,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
WHEN"1110"=>Tone<=CONV_STD_LOGIC_VECTOR(1622,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHEN"1111"=>Tone<=CONV_STD_LOGIC_VECTOR(1728,11);
CODE<=CONV_STD_LOGIC_VECTOR(1,4);
HIGH<='1';
WHENOTHERS=>Tone<=CONV_STD_LOGIC_VECTOR(2047,11);
CODE<=CONV_STD_LOGIC_VECTOR(0,4);HIGH<='0';
ENDCASE;
ENDPROCESS;
END;
PS2VHDL
--VHDLlibraryDeclarations
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------TheEntityDeclarations
ENTITYPS2VHDLISPORT(
ClkFilter:
INSTD_LOGIC;--1MHzRESET:
INSTD_LOGIC;
KBDATA:
INSTD_LOGIC;
KBCLK:
INSTD_LOGIC;
EOC:
OUTSTD_LOGIC;
PDATA:
OUTSTD_LOGIC_VECTOR(7DOWNTO0));
ENDPS2VHDL;
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
--TheArchitectureofEntityDeclarations
ARCHITECTUREBehavioralOFPS2VHDLIS
SIGNALspdata:
STD_LOGIC_VECTOR(10DOWNTO0);
SIGNALTT:
STD_LOGIC;
SIGNALcnt8:
INTEGERRANGE0TO10;
BEGIN-------------------------------------------------
--Optimize
PROCESS(RESET,KBCLK,ClkFilter)
VARIABLECount:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
IF(RESET='0'ORKBCLK='0')THEN
TT<='0';
Count:
=(OTHERS=>'0');
ELSIF(ClkFilter'EVENTANDClkFilter='1')THEN
IF(Count<"1100")THEN
Count:
=Count+1;TT<='0';
ELSE
Count:
="1100";
TT<='1';
ENDIF;
ENDIF;
ENDPROCES---------------------------------------------------Recevie
Recevie:
PROCESS(RESET,TT,KBDATA,spdata,cnt8)
BEGIN
IFRESET='0'THEN
cnt8<=0;spdata<=(OTHERS=>'0');
ELSIFTT'eventANDTT='0'THEN
IF(cnt8<10)THEN
spdata(cnt8)<=KBDATA;
cnt8<=cnt8+1;
ELSE
cnt8<=0;
ENDIF;
ENDIF;
ENDPROCESS;
---------------------------------------------------Endofrecevie
PROCESS(RESET,cnt8)
BEGIN
IFRESET='0'
THENEOC<='0';
ELSIFcnt8/=0
THENEOC<='1';
ELSEEOC<='0';ENDIF;
ENDPROCESS;
--------------------------------------------------------------------------------------------------PDATA<=spdata(8downto1);
ENDBehavioral;
clkdiv10
--占空比为1:
1的任意偶数倍分频
LibraryIEEE;
UseIEEE.std_logic_1164.all;
Useieee.std_logic_unsigned.all;
Entityclkdiv10is
Port(clk:
instd_logic;
clk_out:
outstd_logic);
endclkdiv10;
architecturearchofclkdiv10is
signalcount:
integerrange0to49;--分频倍数-1
begin
process(clk)--分频器
begin
ifclk'eventandclk='1'then
ifcount=count'highthencount<=0;
elsecount<=count+1;
endif;
endif;
endprocess;
process(clk)
begin
ifclk'eventandclk='1'then
ifcount>count'high/2thenclk_out<='1';
elseclk_out<='0';
endif;
endif;
endprocess;
--count_out<=count;
endarch;
clkdiv50
--占空比为1:
1的任意偶数倍分频
LibraryIEEE;
UseIEEE.std_logic_1164.all;
Useieee.std_logic_unsigned.all;
Entityclkdiv50is
Port(clk:
instd_logic;
--count_out:
outintegerrange0to119;
clk_out:
outstd_logic);
endclkdiv50;
architecturearchofclkdiv50is
signalcount:
integerrange0to49;--分频倍数-1
begin
process(clk)--分频器
begin
ifclk'eventandclk='1'then
ifcount=count'highthencount<=0;
elsecount<=count+1;
endif;
endif;
endprocess;
process(clk)
begin
ifclk'eventandclk='1'then
ifcount>count'high/2thenclk_out<='1';
elseclk_out<='0';
endif;
endif;
endprocess;
--count_out<=count;
endarch;
PULSE12
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYPULSE12IS
PORT(CLK:
INSTD_LOGIC;
D:
INSTD_LOGIC_VECTOR(10DOWNTO0);
FOUT:
OUTSTD_LOGIC);
END;
ARCHITECTUREoneOFPULSE12IS
SIGNALFULL:
STD_LOGIC;
SIGNALCNT8:
STD_LOGIC_VECTOR(10DOWNTO0);
SIGNALCNT2:
STD_LOGIC;
BEGIN
P_REG:
PROCESS(CLK)
BEGIN
IFCLK'EVENTANDCLK='1'THEN
IFCNT8="11111111111"THEN
CNT8<=D;--当CNT8计数计满时,输入数据D被同步预置给计数器CNT8
FULL<='1';--同时使溢出标志信号FULL输出为高电平
ELSE
CNT8<=CNT8+1;--否则继续作加1计数
FULL<='0';--且输出溢出标志信号FULL为低电平
ENDIF;
ENDIF;
ENDPROCESSP_REG;
P_DIV:
PROCESS(FULL)
BEGIN
IFFULL'EVENTANDFULL='1'THEN
CNT2<=NOTCNT2;--如果溢出标志信号FULL为高电平,D触发器输出取反
ENDIF;
ENDPROCESSP_DIV;
FOUT<=CNT2;
END;
4、实验总结
通过本次实验,使我对使用VHDL编写模块来实现音乐播放有了更深一步的了解,在本次实验中,在原先的基础上加入了播放暂停的功能,并更换了歌曲。
使仿真更具有功能性,并且更加熟悉了利用数控分频器设计硬件,受益匪浅。