电子琴程序设计与仿真
顶层程序与仿真,音阶发生器程序与仿真,数控分频模块程序与仿真,自动演奏模块程序与仿真设计例
1.顶层程序与仿真
(1)顶层VHDL程序
--文件名:top.vhd
--功能:顶层文件
--最后修改日期:2004.3.20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity top is
Port ( clk32MHz :in std_logic;
--32MHz系统时钟
handTOauto : in std_logic; --键盘输入/自动演奏
code1 :out std_logic_vector(6 downto 0); --音符显示信号
index1 :in std_logic_vector(7 downto 0); --键盘输入信号
high1 :out std_logic; spkout :out std_logic); end top;
architecture Behavioral of top is
component automusic
Port ( clk :in std_logic; Auto: in std_logic; index2:in std_logic_vector(7 downto 0); index0 : out std_logic_vector(7 downto 0)); end component;
--高低音节信号
--音频信号
component tone
Port ( index : in std_logic_vector(7 downto 0);
code : out std_logic_vector(6 downto 0);
high : out std_logic;
tone0 : out integer range 0 to 2047);
end component;
component speaker
Port ( clk1 : in std_logic;
tone1 : in integer range 0 to 2047;
spks : out std_logic);
end component;
signal tone2: integer range 0 to 2047;
signal indx:std_logic_vector(7 downto 0);
begin
u0:automusic port
map(clk=>clk32MHZ,index2=>index1,index0=>indx,Auto=>handtoAuto);
u1: tone port map(index=>indx,tone0=>tone2,code=>code1,high=>high1);
u2: speaker port map(clk1=>clk32MHZ,tone1=>tone2,spks=>spkout);
end Behavioral;
(2)仿真
顶层文件仿真图如图8.17.2所示。
图8.17.2 顶层文件仿真图
2. 音阶发生器程序与仿真
(1) 音阶发生器VHDL程序
--文件名:tone.vhd。
--功能:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity tone is
Port ( index : in std_logic_vector(7 downto 0); code : out std_logic_vector(6 downto 0); high : out std_logic; tone0 : out integer range 0 to 2047); end tone;
architecture Behavioral of tone is
begin
--音符输入信号
--音符显示信号
--高低音显示信号
--音符的分频系数
search :process(index) --此进程完成音符到音符的分频系数译码,音符的显示,高低音阶
begin
case index is
when \"00000001\" => tone0<=773;code<=\"1001111\";high<='1';
when \"00000010\"=> tone0<=912;code<=\"0010010\";high<='1';
when \"00000100\" => tone0<=1036;code<=\"0000110\";high<='1';
when \"00001000\" => tone0<=1116;code<=\"1001100\";high<='1';
when \"00010000\" => tone0<=1197;code<=\"0100100\";high<='1';
when \"00100000\" => tone0<=1290;code<=\"0100000\";high<='0';
when \"01000000\" => tone0<=1372;code<=\"0001111\";high<='0';
when \"10000000\" => tone0<=1410;code<=\"0000000\";high<='0';
when others => tone0<=2047;code<=\"0000001\";high<='0';
end case;
end process;
end Behavioral;
(2)音阶发生器程序仿真
音阶发生器程序仿真图如图8.17.3所示。
图8.17.3 音阶发生器仿真图
3. 数控分频模块程序与仿真
(1) 数控分频模块VHDL程序
--文件名:speaker.vhd。
--功 能:实现数控分频。
--最后修改日期:20004.3.19。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity speaker is
Port ( clk1 : in std_logic; tone1 : in integer range 0 to 30624; spks : out std_logic); end speaker;
architecture Behavioral of speaker is
signal preclk,fullspks:std_logic;
begin
pulse1:process(clk1) 分频
--系统时钟
--音符分频系数
驱动扬声器的音频信号
--此进程对系统时钟进行4 --
variable count:integer range 0 to 8;
begin
if clk1'event and clk1='1' then count:=count+1;
if count=2 then preclk<='1';
elsif count=4 then preclk<='0';count:=0;
end if;
end if;
end process pulse1;
genspks:process(preclk,tone1)
--此进程按照tone1输入的分频系数对8MHz的脉冲再次分频,得到所需要的音符频率
variable count11:integer range 0 to 30624;
begin
if preclk'event and preclk='1' then
if count11 end if; end if; end process; delaysps:process(fullspks) --此进程对fullspks进行2分频 variable count2 :std_logic:='0'; 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 Behavioral; (2) 数控分频模块程序仿真 数控分频模块程序仿真图如图8.17.4所示。 图8.17.4 数控分频模块仿真图 4. 自动演奏模块程序与仿真 (1) 自动演奏模块VHDL程序 --文件名:automusic.vhd --功 能:实现自动演奏功能。 --最后修改日期:2004.3.19。 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity automusic is Port ( clk,Auto : in std_logic; --系统时钟;键盘输入/自动演奏 index2 : in std_logic_vector(7 downto 0); --键盘输入信号 index0 : out std_logic_vector(7 downto 0)); --音符信号输出 end automusic; architecture Behavioral of automusic is signal count0:integer range 0 to 31;--change signal clk2:std_logic; begin pulse0:process(clk,Auto) --此进程完成对系统时钟8M的分频,得到4Hz的信号clk2 variable count:integer range 0 to 8000000; begin if Auto='1' then count:=0;clk2<='0'; elsif clk'event and clk='1' then count:=count+1; if count=4000000(4) then clk2<='1'; elsif count=8000000 (8)then clk2<='0';count:=0; end if; end if; end process; music:process(clk2) --此进程完成自动演奏部分曲的地址累加 begin if clk2'event and clk2='1' then if count0=31 then count0<=0; else count0<=count0+1; end if; end if; end process; com1:process(count0,Auto,index2) begin if Auto='0' then case count0 is --此case语句:存储自动演奏部分的曲 when 0 => index0<=\"00000100\"; --3 when 1 => index0<=\"00000100\"; --3 when 2 => index0<=\"00000100\"; --3 when 3 => index0<=\"00000100\"; --3 when 4 => index0<=\"00010000\"; --5 when 5 => index0<=\"00010000\"; --5 when 6 => index0<=\"00010000\"; --5 when 7 => index0<=\"00100000\"; --6 when 8 => index0<=\"10000000\"; when 9 => index0<=\"10000000\"; when 10 =>index0<=\"10000000\"; when 11=> index0<=\"00000100\"; when 12=> index0<=\"00000010\"; when 13=> index0<=\"00000010\"; when 14=> index0<=\"00000001\"; when 15=> index0<=\"00000001\"; when 16=> index0<=\"00010000\"; when 17=> index0<=\"00010000\"; --8 --8 --8 --3 --2 --2 --1 --1 --5 --5 when 18=> index0<=\"00001000\"; --4 when 19=> index0<=\"00001000\"; --4 when 20=> index0<=\"00001000\"; --4 when 21=> index0<=\"00000100\"; when 22=> index0<=\"00000010\"; when 23=> index0<=\"00000010\"; when 24=> index0<=\"00010000\"; when 25=> index0<=\"00010000\"; when 26=> index0<=\"00001000\"; when 27=> index0<=\"00001000\"; when 28=> index0<=\"00000100\"; when 29=> index0<=\"00000100\"; when 30=> index0<=\"00000010\"; --3 --2 --2 --5 --5 --4 --4 --3 --3 --2 when 31=> index0<=\"00000010\"; --2 when others => null; end case; else index0<=index2; --键盘输入音符信号输出 end if; end process; end Behavioral; (2)自动演奏模块程序仿真 自动演奏模块仿真图如图8.17.5所示。 图8.17.5 自动演奏模块仿真图 (注:由于输入频率太高,实验条件所限,如按源程序仿真将看不到输出波形,因此将原脉冲的分频点4000000和8000000改为4和8,得到如图的仿真结果,在实际烧制 芯片中不作此处理。) 因篇幅问题不能全部显示,请点此查看更多更全内容