重庆交通大学计算机与信息学院设计性实验报告班级:通信工程专业 07 级 2 班姓名(学号):实验项目名称:乐器演奏电路设计实验项目性质:设计性实验所属课程: VHDL 实验室(中心):指导教师:徐雯娟实验完成时间: 2009 年 12 月 13 日一、实验目的1,了解普通扬声器的工作原理;2,了解QuartusII4.1中提供了宏功能元件库mega_lpm。
3,使用LPM_ROM参数化存储模块。
二、实验内容及要求要求能够演奏出《友谊地久天长》的曲调或可另选一段较完整的曲调。
(扩展要求:能够从数码管上显示出当前曲调的简谱和频率)三、实验原理1,音符的频率:可以由上图中的U3获得,这是一个数控分频器。
由其clk 端输入一具有较高频率(这里是12MHz)的信号,通过U3分频后由SPKOUT输出,U3对clk 输入信号的分频比由11位预置数Tone[10..0]决定。
SPKOUT的输出频率将决定每一音符的音调,这样,分频计数器的预置值Tone[10..0]与SPKOUT 的输出频率,就有了对应关系。
2,音符的持续时间:须根据乐曲的速度及每个音符的节拍数来确定,图中模块U2的功能首先是为U3提供决定所发音符的分频预置数,而此数在U3输入口停留的时间即为此音符的节拍值。
模块U2是乐曲简谱码对应的分频预置数查表电路,其中设置了乐曲全部音符所对应的分频预置数(一共8个),每一音符的停留时间由音乐节拍和音调发生器模块U1的clk的输入频率决定(如为4Hz),这8个值的输出由对应于U2的3位输入值Index[2..0]确定。
3,乐谱的存储:在U1中设置了一个7位二进制计数器(计数最大值为65),作为音符数据ROM 的地址发生器。
这个计数器的计数频率若选为4Hz,即每一计数值的停留时间为0.25秒,恰为当全音符设为1秒时,四四拍的4分音符持续时间。
随着U1中的计数器按4Hz的时钟速率作加法计数时,即随地址值递增时,音符数据ROM 中的音符数据将从ROM中通过ToneIndex[2..0]端口输向U2模块,乐曲就开始连续自然地演奏起来了。
四、实验仪器、材料1,2MHZ和4HZ的信号源2,ACEX1K EP1K30TC144—1芯片3,扬声器五、方案设计(设计性实验需要,综合性实验无该项)1,音符的产生:音符的产生是利用数控分频器模块SPKEAR对输入的时钟信号CLK400KHZ进行分频,预置数为TONE[10..0],然后分频得出频率为CLK/2*(2048- TONE[10..0]),通过控制输入预置数TONE[10..0]来达到不同的输出频率,以达到控制扬声器发出不同的声音。
例如:当设置预置数TONE[10..0]为1538时,输出SPKEAR频率为396,为低音5。
2,频率的分频:由于实验给定信号源为12MHZ,不满足数控分频器模块SPKEAR对输入时钟信号的要求,遂其进行30分频(PULSE30),产生0.4MHZ的时钟信号。
3,预置数的产生:预置数TONE[10..0]由模块TONE TAB产生。
模块TONE TAB有输入端口INDEX[2..0]送入音符,模块由CASE选择语句产生与INDEX[2..0]输入端口送入的音符相对应的预置数TONE[10..0],也同时产生其音符CODE[2..0]送入音符显示模块DISPCODE,和频谱频率frenquence[9..0]送入频率显示模块DISPFREN。
例如:当输入端口INDEX[2..0]送入000(为低音5对应的编码),有CAES选择语句产生TONE[10..0]为1538,frenquence[9..0]为396 以及CODE[2..0]为101的输出。
4,音符的存储:音符的持续时间须根据乐曲的速度及每个音符的节拍数来确定。
由存储模块music_rom_data控制,以四分之一节拍为1个单位在LPM_ROM中进行存储音符的编码(例如本实验《友谊地久天长》中频谱共涉及了8个音符,使用3个二进制数分别对其编码进行存储;又有二分之一节拍数的音符存储2个单元,以此类推,直到对整首歌曲的乐谱存储结束)。
存储模块music_rom_data的输出为数控分频器模块TONETAB的输入端INDEX[2..0]。
5,音符的输出驱动:音符的存储由计数器模块LPM_COUNTE控制。
计数器在时钟CLK4HZ的控制下,没0.25s 送出一个6位数值q[5..0],作为存储模块music_rom_data的地址输入端口。
这样便达到每个存储单元以同一频率进行有控制的输出。
6,频谱显示模块DISPCODE和频率显示模块DISPFRENQUENCE有本组另一同学(袁亮)设计。
六、实验过程及原始记录1,制作存储模块music_rom_data.(1)定制LPM_ROM初始化数据文件建立.mif格式文件:选择File—>New—>Memory Initialization File项,选择数据位为256,数据宽度为8,建立.mif格式文件,将歌曲频谱以编码的形式,以四分之一节拍为一单位进行存储。
(其实128位数据位已经够本实验歌曲《友谊地久天长》使用)形成如下图的数据文件:(2),定制LPM_ROM元件①LPM宏功能模块设定②选择ROM_DATA模块数据线和地址线宽度③调入ROM初始化数据文件④LPM_ROM设计完成生成用于例化的LPM_ROM的VHDL文件music_data_rom.vhd:LIBRARY ieee;USE ieee.std_logic_1164.all;LIBRARY lpm;USE lpm.lpm_components.all;ENTITY music_data_rom ISPORT(address : IN STD_LOGIC_VECTOR (5 DOWNTO 0);q : OUT STD_LOGIC_VECTOR (2 DOWNTO 0));END music_data_rom;ARCHITECTURE SYN OF music_data_rom ISSIGNAL sub_wire0 : STD_LOGIC_VECTOR (2 DOWNTO 0);COMPONENT lpm_romGENERIC (intended_device_family : STRING;lpm_width : NATURAL;lpm_widthad : NATURAL;lpm_address_control : STRING;lpm_outdata : STRING;lpm_file : STRING;lpm_type : STRING);PORT (address : IN STD_LOGIC_VECTOR (5 DOWNTO 0);q : OUT STD_LOGIC_VECTOR (2 DOWNTO 0));END COMPONENT;BEGINq <= sub_wire0(2 DOWNTO 0);lpm_rom_component : lpm_romGENERIC MAP (intended_device_family => "ACEX1K", lpm_width => 3,lpm_widthad => 6,lpm_address_control => "UNREGISTERED",lpm_outdata => "UNREGISTERED",lpm_file => "music_rom_data.mif",lpm_type => "LPM_ROM")PORT MAP (address => address,q => sub_wire0);END SYN;2,制作计数器模块COUNTER实验步骤如上:生成用于例化的LPM_COUNTER的VHDL文件counter.vhd:LIBRARY ieee;USE ieee.std_logic_1164.all;LIBRARY lpm;USE lpm.all;ENTITY counter ISPORT(clk_en : IN STD_LOGIC ;clock : IN STD_LOGIC ;q : OUT STD_LOGIC_VECTOR (5 DOWNTO 0)); END counter;ARCHITECTURE SYN OF counter ISSIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0);COMPONENT lpm_counterGENERIC (lpm_direction : STRING;lpm_port_updown : STRING;lpm_type : STRING;lpm_width : NATURAL);PORT (clk_en : IN STD_LOGIC ;clock : IN STD_LOGIC ;q : OUT STD_LOGIC_VECTOR (5 DOWNTO 0));END COMPONENT;BEGINq <= sub_wire0(5 DOWNTO 0);lpm_counter_component : lpm_counterGENERIC MAP (lpm_direction => "UP",lpm_port_updown => "PORT_UNUSED",lpm_type => "LPM_COUNTER",lpm_width => 6)PORT MAP (clk_en => clk_en,clock => clock,q => sub_wire0);END SYN;3,制作数控分频器SPKEAR模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY speaker ISPORT(CLK: IN STD_LOGIC;tone:IN integer range 0 to 2048;spks:out std_logic);END speaker;ARCHITECTURE ONE OF speaker ISSIGNAL FULL: STD_LOGIC;BEGINP_REG: PROCESS(CLK)VARIABLE CNT8:integer range 0 to 2048;BEGINIF CLK'EVENT AND CLK='1' THENIF CNT8=2048 THENCNT8:=tone;FULL<='1';ELSE CNT8:=CNT8+1;FULL<='0';END IF;END IF;END PROCESS P_REG;P_DIV:PROCESS(FULL)VARIABLE CNT2:STD_LOGIC;BEGINIF FULL'EVENT AND FULL='1' THEN CNT2:=NOT CNT2;IF CNT2='1' THEN spks<='1'; ELSE spks<='0';END IF;END IF;END PROCESS P_DIV;END ONE;4,制作TONE TAB模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity tonetab isport(index: in std_logic_vector(2 downto 0);tone : out integer range 0 to 2048;frequence : out integer range 0 to 990;code : out std_logic_vector(2 downto 0));end entity;architecture behave_tonetab of tonetab isbeginprocess(index)begincase index iswhen "000"=> frequence<=396;code<="101";tone<=1538; when "001"=> frequence<=523code<="001";tone<=1666; when "010"=> frequence<=587;code<="010";tone<=1708; when "011"=> frequence<=659;code<="011";tone<=1745; when "100"=> frequence<=784;code<="101";tone<=1794; when "101"=> frequence<=1047;code<="110";tone<=1821; when "110"=> frequence<=1175;code<="001";tone<=1857; when "111"=> frequence<=440;code<="110";tone<=1595; end case;end process;end behave_tonetab;5,制定PULSE30模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity pulse30 isport(clk :in std_logic;fout:out std_logic);end;architecture behave_pulse30 of pulse30 isSIGNAL FULL: STD_LOGIC;BEGINP1: PROCESS(CLK)VARIABLE CNT30:integer range 1 to 30;BEGINIF CLK'EVENT AND CLK='1' THENIF CNT30=30 THENCNT30:=1;FULL<='1';ELSE CNT30:=CNT30+1;FULL<='0';END IF;END IF;END PROCESS P1;P2:PROCESS(FULL)VARIABLE CNT2:STD_LOGIC;BEGINIF FULL'EVENT AND FULL='1' THEN CNT2:=NOT CNT2;IF CNT2='1' THEN fout<='1'; ELSE fout<='0';END IF;END IF;END PROCESS P2;END behave_pulse30;七、实验结果及分析实验结果:当en_clock=’1’时,即clock有效时,试验箱端扬声器演奏出乐曲《友谊地久天长》的音乐。