资源描述
1.软件硬件
1 EP3C40Q240C8芯片
2 实验箱底板电路(包括 蜂鸣器、7段数码管、Led灯1个、拨码开关3个、Key按键7个)
3 QuartusⅡ9.0
4 计算
2. 总体模块功能
1 使用两个时钟分别为12MHz和8Hz的时钟,分别供分频驱动器(数控分频器)与计数器使用。
2 计数器完成计数功能,分为两个计数器counter1和counter2,counter1计数到269,counter2计数到163,都是在上升沿来临时计数。
3 四个音乐模块分别记录了2首歌的乐谱。根据上一模块计数器所计的数读取相应地址里的数据传递给下一模块。
4 选择器完成选择歌曲的功能。
5 数据翻译模块将选择器所选择的歌曲里的地址的数据翻译成分频驱动器(数控分频器)分频所需的控制数据、1个led灯数据(中低音)、以及译码器所需的数据。
6 分频驱动器也就是一个数控分频器,完成分频的功能,并驱动蜂鸣器。
7 译码器将乐谱数据在led数码管上显示。
图3-2 小糊涂神曲谱
3.各个模块图形及程序
3.1 计数器及歌曲存储模块(notetabs)
计数器完成计数功能,分为两个计数器,分别计到269和163,因为两首歌曲的最大字符分别为269和163,存储的两首歌是《采蘑菇的小姑娘》、《小糊涂神》,曲谱如下:
图3-1 采蘑菇的小姑娘曲谱
1 模块图形
模块如图3-3所示:
图3-3 notetabs模块图形
2 程序
由于此程序较多,在附录中给出,见附录
3 仿真波形图
仿真图如图3-4所示:
图3-4 notetabs仿真波形图
通过仿真图可以清楚的看到,每计一次数输出toneindex的值随之发生一定的变化,只不过根据乐谱的不同,输出的变化也不尽相同。例如在本次设计中,自第8个时钟上升沿来临到第15个时钟上升沿,输出toneindex2均选取音符“5”。然后把输出toneindex2输入到音调编码器模块,进行下一步编码工作。
3.2 手动模块(tone)
可通过7个按键手动的进行演奏,7个按键分别代表7个音。
1 模块图形
模块如图3-5所示:
图3-5 tone 模块图形
4.程序
library ieee;
use ieee.std_logic_1164.all;
entity tone is
port(key:in std_logic_vector(6 downto 0);
toneindex1:out std_logic_vector(3 downto 0));
end;
architecture one of tone is
begin
search:process(key)
begin
case key is
when"0000001"=>toneindex1<="0001";
when"0000010"=>toneindex1<="0010";
when"0000100"=>toneindex1<="0011";
when"0001000"=>toneindex1<="0100";
when"0010000"=>toneindex1<="0101";
when"0100000"=>toneindex1<="0110";
when"1000000"=>toneindex1<="0111";
when others=>toneindex1<="0000";
end case;
end process;
end;
3 仿真波形图
仿真图如图3-6所示:
图3-6 tone 仿真波形
在此仿真图中不同的key相当于对应不同的琴键,当按下不同的琴键时输出相对应的toneindex1,toneindex1在输入音调编码器中进行下一步编码。
3.3.3 手动、自动选择模块(mux)
根据设计的要求,该简易乐曲演奏器能实现手动或自动演奏乐曲的功能。于是,可通过一个按键cs来进行自动与手动的选择,当cs按下时,乐曲自动演奏,其他情况下均为手动演奏乐曲,即可以通过按下其他的按键(与cs相连的按键除外)来控制不同的音符。与此同时,还需要一个复位信号rst来控制该演奏器是否工作,当rst为1时,停止演奏,为0时,可以演奏。以上提到的手动与自动的选择只能在rst为0时有效。
1 模块图形
模块图形如图3-7所示:
图3-7 mux 模块图形
2 程序
library ieee;
use ieee.std_logic_1164.all;
entity mux is
port(rst:in std_logic;
index1:in std_logic_vector(3 downto 0);
index2:in std_logic_vector(3 downto 0);
cs :in std_logic;
toneindex:out std_logic_vector(3 downto 0));
end;
architecture arc_mux of mux is
begin
process(cs)
begin
if rst='1'then toneindex<="0000";
else
case cs is
when '0'=>toneindex<=index1;
when '1'=>toneindex<=index2;
when others=>toneindex<=null;
end case;
end if;
end process;
end arc_mux;
3 仿真波形图
仿真波形图如图3-8所示:
图3-8 mux仿真波形图
此仿真图中输入cs代表手动\自动演奏的选择端,输入rst代表整体复位端,输入index1、index2分别代表手动和自动要演奏的音符,输出q代表经过选择后,要演奏的或是手动输入或是自动输入的音符。由此仿真图可清楚的看到当rst=1时,不论选择的是手动还是自动,输出都为零,达到了整体复位的功能;当rst=0且cs=1时,自动演奏乐曲,因为q与index2的值相同;当rst=0且cs=0时,手动演奏乐曲,因为这时的q与index1的值相同,从而也达到了演奏方式选择的功能。
3.3.4 音调编码器(tonetaba)
1 模块图形
模块图形如图3-9所示:
图3-9 tonetaba模块图形
2 程序
见附录
3 仿真波形图
仿真图形如图3-10所示:
图3-10 tonetaba 仿真波形图
在此仿真图中从上到下依次代表输出code、high、输入index和输出tone。通过此仿真图能清楚的看到当音符分别为4、10、8、15时,它们所对应的分频预置数tone分别是1116、1542、1410、1728;所对应的音谱code分别是4、3、1、1。其中code、high1能分别在数码管和led上显示,而tone则输入到数控分频模块作为分频的依据。于是,由仿真图印证了音调编码模块传送预置数及显示功能。
3.3.5 数控分频器(speakera)
将芯片上提供的50MHz的时钟分频为12MHz和8Hz的时钟,分别供计数器与分频驱动器(数控分频器)使用。
1 模块图形:
模块图形如图3-11所示:
图3-11 speakera模块图形
2 程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY Speakera IS
PORT ( clk : IN STD_LOGIC;
Tone : IN STD_LOGIC_VECTOR (10 DOWNTO 0);
SpkS : OUT STD_LOGIC );
END;
ARCHITECTURE one OF Speakera IS
SIGNAL PreCLK, FullSpkS : STD_LOGIC;
BEGIN
DivideCLK : PROCESS(clk)
VARIABLE Count4 : STD_LOGIC_VECTOR (3 DOWNTO 0) ;
BEGIN
PreCLK <= '0';
IF Count4>11 THEN PreCLK <= '1'; Count4 := "0000";
ELSIF clk'EVENT AND clk = '1' THEN Count4 := Count4 + 1;
END IF;
END PROCESS;
GenSpkS : PROCESS(PreCLK, Tone)
VARIABLE Count11 : STD_LOGIC_VECTOR (10 DOWNTO 0);
BEGIN
IF PreCLK'EVENT AND PreCLK = '1' THEN
IF Count11 = 16#7FF# THEN Count11 := Tone ; FullSpkS <= '1';
ELSE Count11 := Count11 + 1; FullSpkS <= '0'; END IF;
END IF;
END PROCESS;
DelaySpkS : PROCESS(FullSpkS)
VARIABLE Count2 : STD_LOGIC;
BEGIN
IF FullSpkS'EVENT AND FullSpkS = '1' THEN Count2 := NOT Count2;
IF Count2 = '1' THEN SpkS <= '1';
ELSE SpkS <= '0'; END IF;
END IF;
END PROCESS;
END;
3 仿真波形图
仿真图如图3-12所示:
图3-12 speakera 仿真波形图
在此仿真图中,输入clk是一个频率较大的时钟信号,输入tone代表着某个音符的分频预置数,输出spks则代表将输入clk先经过12次分频,再经过(预置数终值2048-tone)次分频,最终在进行二分频处理后的信号,而这个信号的频率就是我们需要演奏的音谱的频率,根据频率的不同,从而能通过喇叭听到不同的声音,这就是我们一直想要演奏的乐曲了。
3.4 硬件设计及仿真分析
3.4.1 顶层音乐演奏器原理图
经过了各个子模块的分析与验证后,我们只需将各个子模块之间的输入输出端、子模块与整体电路之间的输入输出端进行正确的硬件连接就得到了顶层音乐演奏器的原理图,如图3-13
图3-13 自行连接的音乐演奏器原理图
3.4.2 顶层文件仿真波形分析
首先,介绍一下总体程序中各个引脚的作用及硬件连接情况:输入clk8Hz是一个频率较小的时钟信号,在进行硬件下载时它与实验箱上标准时钟信号源模块的8Hz频率相连,它决定着乐曲演奏的快慢;输入clk12mHz是一个频率较大的时钟信号,因为要对它进行多次不同的分频,下载时它与实验箱上标准时钟信号源模块的20MHz频率相连;输入key[6..0]是当手动演奏时自己确定的音符,;输入rst和cs分别是整体复位端和演奏方式选择端;输出code1和high1分别用来显示音谱与高中低音,它们分别与实验箱上的数码管1和led1相连;输出spkout要与实验箱上的喇叭相连,用来发出声音。
其次,顶层电路的仿真波形图是否正确依赖于各个子模块的功能是否完善,同时顶层电路的功能实现又验证了各个子模块的正确性,二者相互依存。
最后,由仿真波形图印证了整体电路的功能
3.4.3 顶层文件的管脚分配以及硬件连接图
下载到硬件时管脚的连接图如图3-14
图3-14 管脚分配图
硬件的连接图如图3-15所示:
图3-15 硬件连接图
对应着管脚分配图和硬件连接图可看出硬件芯片分别连接了上方的七段数码管,左方的7个白色按键key和标准时钟信号源,下方的led灯,蜂鸣器和右下方的三个拨码开关。
4 设计总结
1 本次简易乐曲演奏器的设计经过了整体分析、模块化分析、整体与模块的仿真分析这样三个步骤,硬件实现了整体复位、按键选择演奏方式、循环演奏以及数码管显示乐谱的功能。
2 在做数控分频器模块的仿真时一定要处理好时序问题。
3 本文介绍了基于 FPGA 的音乐硬件演奏电路的设计,实现了一个乐曲播放器,乐曲 演奏器的设计经过了整体分析、模块化分析、整体与模块的仿真分析这样三个步骤,硬 件实现了循环演奏以及数码管显示乐谱的功能, 描述了其工作原理、设计思路及实现方 法,并在QuartusII 上选用目标芯片仿真实现了音乐硬件演奏电路的功能。实践证明: 采用 FPGA 设计实现音乐硬件演奏电路的可行性和可靠性,而且更改乐曲容易,可根据 需要修改 ROM 中的音符数据文件,从而使电路实现任一曲子的播放。这种基于 FPGA 的音乐硬件演奏电路的设计与实现不仅通过 VHDL 层次化和模块化,同时采用数控分频的设计思想,更好的优化了乐曲演奏数字电路的设计,在此基础上不必变化顶层文件架构可随意变更乐曲,有效缩短了产品开发周期、减少了设计芯片的数量、降低了功耗、提高了设计的灵活性、可靠性和可扩展性 本次设计可以说达到了设计要求,但尚有需要改进的地方。随着乐谱的复杂程度加大, 如果依然在音调发生器的程序中通过时钟计数来决定音符的输出,会加大编程的繁杂 度, 这时一个很好的解决办法就是把将要演奏的乐谱存放在人为开辟的存储空间里, 这样只需要在相应地址中读出音符即可。
5 设计心得与感想
在这 2 周里我用 EDA 的知识完成了乐曲硬件演奏电路的设计,这使我对这门课程有 了更深一步的了解。 随着科学技术的发展,电子信息技术与人们的生活已经分不开,可以说人们 走到哪里都离不开电子产品,如我们常遇到的交通信号灯,出租车计价器,家用 电器更不用说。 我很荣幸能选择到这个专业学习,我想我会在今后的工作生活中, 能用所学的知识为人们创造出更多更方便的东西来满足人们的需要。 在这 2 周里,我通过查找资料,向老师请教等完成了乐曲硬件演奏电路的设 计,以前在课堂上只是听老师说 EDA 是门很常用的学科,能完成各种仪器的编 程等,但从来没有应用到实践中来,所以我以前对这门课感到很陌生,不知道怎 么才能将这门课应用到实践。不过在这 2 周里,我认真的查找资料,上机调试, 使我对这门课有了更进一步的认识,它功能强大,应用到的范围也非常的广,因 此我很高兴能学到这么一门有用的学科。通过这 2 周的时间,我把以前学过的知 识从理论应用到了实践,这大大培养了我独立思考的能力和动手能力,也锻炼了 我遇到困难不要受到挫折的心理,我感到个人能力又得到了提高。总之,这次课程设计为我以后的工作奠定了坚实的基础,充分锻炼了我的个人能力,作为电子信息工程专业的一名学生,我会在以后的工作生活中不段磨练自己,为社会创造出更多有益于人们生活的产品来。
6 参考文献
[1].潘松、黄继业等编著. EDA 技术与 VHDL[M].北京:清华大学出版社
[2].边计年主编.用 VHDL 设计电子线路[M].北京:清华大学出版社
[3].王金明,杨吉斌等编著.数字系统设计与 Verilog HDL[D].北京:电子工业出版社
[4].徐志军,徐光辉等编著.CPLD/FPGA 开发与应用[M].北京:电子工业出版社
[5].潘松,黄继业等编著.EDA 技术实用教程(第 2 版)[M].北京:科学出版社
[6].叶天迟主编.EDA 实用技术实验及课程设计指导书[M].长春:自编实验指导书
附录
1 notetabs程序
library ieee;
use ieee.std_logic_1164.all;
entity notetabs is
port(rst:in std_logic;
CLK:in std_logic;
d:in std_logic;
toneindex2:out std_logic_vector(3 downto 0));
end notetabs;
architecture one of notetabs is
signal counter1:integer range 0 to 269;
signal counter2:integer range 0 to 163;
begin
cnt8:process(clk)
begin
if rst='1' then counter1<=0;counter2<=0;
elsif counter1=269 then
counter1<=0;
elsif counter2=163 then
counter2<=0;
elsif clk'event and clk='1'then
counter1<=counter1+1;
counter2<=counter2+1;
end if;
end process;
search:process(counter1,counter2)
begin
if d='0'then
case counter1 is
when 0=>toneindex2<="0110";when 1=>toneindex2<="0110";
when 2=>toneindex2<="0110";when 3=>toneindex2<="0110";
when 4=>toneindex2<="1010";when 5=>toneindex2<="1010";
when 6=>toneindex2<="1010";when 7=>toneindex2<="1010";
when 8=>toneindex2<="1010";when 9=>toneindex2<="1010";
when 10=>toneindex2<="1010";when 11=>toneindex2<="1010";
when 12=>toneindex2<="1010";when 13=>toneindex2<="1010";
when 14=>toneindex2<="1010";when 15=>toneindex2<="1010";
when 16=>toneindex2<="1010";when 17=>toneindex2<="1010";
when 18=>toneindex2<="1001";when 19=>toneindex2<="1001";
when 20=>toneindex2<="1000";when 21=>toneindex2<="1000";
when 22=>toneindex2<="1000";when 23=>toneindex2<="1000";
when 24=>toneindex2<="1001";when 25=>toneindex2<="1001";
when 26=>toneindex2<="1001";when 27=>toneindex2<="1001";
when 28=>toneindex2<="0000";when 29=>toneindex2<="0000";
when 30=>toneindex2<="0000";when 31=>toneindex2<="0000";
when 32=>toneindex2<="1001";when 33=>toneindex2<="1001";
when 34=>toneindex2<="1001";when 35=>toneindex2<="1001";
when 36=>toneindex2<="1001";when 37=>toneindex2<="1001";
when 38=>toneindex2<="1010";when 39=>toneindex2<="1010";
when 40=>toneindex2<="1001";when 41=>toneindex2<="1001";
when 42=>toneindex2<="1001";when 43=>toneindex2<="1001";
when 44=>toneindex2<="1000";when 45=>toneindex2<="1000";
when 46=>toneindex2<="1000";when 47=>toneindex2<="1000";
when 48=>toneindex2<="1001";when 49=>toneindex2<="1001";
when 50=>toneindex2<="1000";when 51=>toneindex2<="1000";
when 52=>toneindex2<="0110";when 53=>toneindex2<="0110";
when 54=>toneindex2<="0101";when 55=>toneindex2<="0101";
when 56=>toneindex2<="0110";when 57=>toneindex2<="0110";
when 58=>toneindex2<="0110";when 59=>toneindex2<="0110";
when 60=>toneindex2<="0000";when 61=>toneindex2<="0000";
when 62=>toneindex2<="0000";when 63=>toneindex2<="0000";
when 64=>toneindex2<="0011";when 65=>toneindex2<="0011";
when 66=>toneindex2<="0011";when 67=>toneindex2<="0011";
when 68=>toneindex2<="0011";when 69=>toneindex2<="0011";
when 70=>toneindex2<="0101";when 71=>toneindex2<="0101";
when 72=>toneindex2<="0101";when 73=>toneindex2<="0101";
when 74=>toneindex2<="0101";when 75=>toneindex2<="0101";
when 76=>toneindex2<="0101";when 77=>toneindex2<="0101";
when 78=>toneindex2<="0101";when 79=>toneindex2<="0101";
when 80=>toneindex2<="0101";when 81=>toneindex2<="0101";
when 82=>toneindex2<="0101";when 83=>toneindex2<="0101";
when 84=>toneindex2<="0101";when 85=>toneindex2<="0101";
when 86=>toneindex2<="0110";when 87=>toneindex2<="0110";
when 88=>toneindex2<="1001";when 89=>toneindex2<="1001";
when 90=>toneindex2<="1000";when 91=>toneindex2<="1000";
when 92=>toneindex2<="1000";when 93=>toneindex2<="1000";
when 94=>toneindex2<="0000";when 95=>toneindex2<="0000";
when 96=>toneindex2<="0000";when 97=>toneindex2<="0000";
when 98=>toneindex2<="0110";when 99=>toneindex2<="0110";
when 100=>toneindex2<="0110";when 101=>toneindex2<="0110";
when 102=>toneindex2<="0110";when 103=>toneindex2<="0110";
when 104=>toneindex2<="1000";when 105=>toneindex2<="1000";
when 106=>toneindex2<="1001";when 107=>toneindex2<="1001";
when 108=>toneindex2<="1001";when 109=>toneindex2<="1001";
when 110=>toneindex2<="1000";when 111=>toneindex2<="1000";
when 112=>toneindex2<="0010";when 113=>toneindex2<="0010";
when 114=>toneindex2<="1010";when 115=>toneindex2<="1010";
when 116=>toneindex2<="1010";when 117=>toneindex2<="1010";
when 118=>toneindex2<="1010";when 119=>toneindex2<="1010";
when 120=>toneindex2<="1010";when 121=>toneindex2<="1010";
when 122=>toneindex2<="1010";when 123=>toneindex2<="1010";
when 124=>toneindex2<="1010";when 125=>toneindex2<="1010";
when 126=>toneindex2<="1010";when 127=>toneindex2<="1010";
when 128=>toneindex2<="1010";when 129=>toneindex2<="1010";
when 130=>toneindex2<="0110";when 131=>toneindex2<="0110";
when 132=>toneindex2<="0110";when 133=>toneindex2<="0110";
when 134=>toneindex2<="1010";when 135=>toneindex2<="1010";
when 136=>toneindex2<="1010";when 137=>toneindex2<="1010";
when 138=>toneindex2<="1010";when 139=>toneindex2<="1010";
when 140=>toneindex2<="1010";when 141=>toneindex2<="1010";
when 142=>toneindex2<="1010";when 143=>toneindex2<="1010";
when 144=>toneindex2<="1010";when 145=>toneindex2<="1010";
when 146=>toneindex2<="1010";when 147=>toneindex2<="1010";
when 148=>toneindex2<="1001";when 149=>toneindex2<="1001";
when 150=>toneindex2<="1010";when 151=>toneindex2<="1010";
when 152=>toneindex2<="1000";when 153=>toneindex2<="1000";
when 154=>toneindex2<="1000";when 155=>toneindex2<="1000";
when 156=>toneindex2<="1001";when 157=>toneindex2<="1001";
when 158=>toneindex2<="1001";when 159=>toneindex2<="1001";
when 160=>toneindex2<="0000";when 161=>toneindex2<="0000";
when 162=>toneindex2<="0000";when 163=>toneindex2<="0000";
when 164=>toneindex2<="1001";when 165=>toneindex2<="1001";
when 166=>toneindex2<="1001";when 167=>toneindex2<="1001";
when 168=>toneindex2<="1001";when 169=>toneindex2<="1001";
when 170=>toneindex2<="1010";when 171=>toneindex2<="1010";
when 172=>toneindex2<="1001";when 173=>toneindex2<="1001";
when 174=>toneindex2<="1001";when 175=>toneindex2<="1001";
when 176=>toneindex2<="1000";when 177=>toneindex2<="1000";
when 178=>toneindex2<="1000";when 179=>toneindex2<="1000";
when 180=>toneindex2<="1001";when 181=>toneindex2<="1001";
when 182=>toneindex2<="1000";when 183=>toneindex2<="1000";
when 184=>toneindex2<="0110";when 185=>toneindex2<="0110";
when 186=>toneindex2<="0101";when 187=>toneindex2<="0101";
when 188=>toneindex2<="0110";when 189=>toneindex2<="0110";
when 190=>toneindex2<="0110";when 191=>toneindex2<="0110";
when 192=>toneindex2<="0000";when 193=>toneindex2<="0000";
when 194=>toneindex2<="0000";when 195=>toneindex2<="0000";
when 196=>toneindex2<="0011";when 197=>toneindex2<="0011";
when 198=>toneindex2<="0011";when 199=>toneindex2<="0011";
when 200=>toneindex2<="0011";when 201=>toneindex2<="0011";
when 202=>toneindex2<="0101";when 203=>toneindex2<="0101";
when 204=>toneindex2<="0101";when 205=>toneindex2<="0101";
when 206=>toneindex2<="0101";when 207=>toneindex2<="0101";
when 208=>toneindex2<="0101";when 209=>toneindex2<="0101";
when 210=>toneindex2<="0101";when 211=>toneindex2<="0101";
when 212=>toneindex2<="0110";when 213=>toneindex2<="0110";
when 214=>toneindex2<="0110";when 215=>toneindex2<="0110";
when 216=>toneindex2<="0010";when 217=>toneindex2<="0010";
when 218=>toneindex2<="1000";when 219=>toneindex2<="1000";
when 220=>toneindex2<="1000";when 221=>toneindex2<="1000";
when 222=>toneindex2<="0000";when 223=>toneindex2<="0000";
when 224=>toneindex2<="0001";when 225=>toneindex2<="0001";
when 226=>toneindex2<="1001";when 227=>toneindex2<="1001";
when 228=>toneindex2<="1001";when 229=>toneindex2<="1001";
when 230=>toneindex2<="1000";when 231=>toneindex2<="1000";
when 232=>toneindex2<="0110";when 233=>toneindex2<="0110";
when 234=>toneindex2<="0110";when 235=>toneindex2<="0110";
when 236=>toneindex2<="0101";when 237=>toneindex2<="0101";
when 238=>toneindex2<="0101";when 239=>toneindex2<="0101";
when 240=>toneindex2<="0011";when 241=>toneindex2<="00
展开阅读全文