程序設(shè)計(jì)與仿真 電子琴VHDL程序包含有:頂層程序、音階發(fā)生器程序、數(shù)控分頻模塊程序和自動演奏模塊程序。 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系統(tǒng)時(shí)鐘 handTOauto : in std_logic; --鍵盤輸入/自動演奏 code1 :out std_logic_vector(6 downto 0); --音符顯示信號 index1 :in std_logic_vector(7 downto 0); --鍵盤輸入信號 high1 :out std_logic; --高低音節(jié)信號 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.18.2所示。 圖8.18.2 頂層文件仿真圖 2. 音階發(fā)生器程序與仿真 --文件名: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); --音符的分頻系數(shù) end tone; architecture Behavioral of tone is begin search :process(index) --此進(jìn)程完成音符到音符的分頻系數(shù)譯碼,音符的顯示,高低音階 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)音階發(fā)生器程序仿真 音階發(fā)生器程序仿真圖如圖8.18.3所示。 圖8.18.3 音階發(fā)生器仿真圖 3. 數(shù)控分頻模塊程序與仿真 --文件名:speaker.vhd。 --功 能:實(shí)現(xiàn)數(shù)控分頻。 --最后修改日期: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; --系統(tǒng)時(shí)鐘 tone1 : in integer range 0 to 30624; --音符分頻系數(shù) spks : out std_logic); --驅(qū)動揚(yáng)聲器的音頻信號 end speaker; architecture Behavioral of speaker is signal preclk,fullspks:std_logic; begin pulse1:process(clk1) --此進(jìn)程對系統(tǒng)時(shí)鐘進(jìn)行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) --此進(jìn)程按照tone1輸入的分頻系數(shù)對8MHz的脈沖再次分頻,得到所需要的音符頻率 variable count11:integer range 0 to 30624; begin if preclk'event and preclk='1' then if count11<tone1 then count11:=count11+1;fullspks<='1'; else count11:=0;fullspks<='0'; end if; end if; end process; delaysps:process(fullspks) --此進(jìn)程對fullspks進(jìn)行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) 數(shù)控分頻模塊程序仿真 數(shù)控分頻模塊程序仿真圖如圖8.18.4所示。 圖8.18.4 數(shù)控分頻模塊仿真圖 4. 自動演奏模塊程序與仿真 --文件名:automusic.vhd --功 能:實(shí)現(xiàn)自動演奏功能。 --最后修改日期: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; --系統(tǒng)時(shí)鐘;鍵盤輸入/自動演奏 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) --此進(jìn)程完成對系統(tǒng)時(shí)鐘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) --此進(jìn)程完成自動演奏部分曲的地址累加 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"; --8 when 9 => index0<="10000000"; --8 when 10 =>index0<="10000000"; --8 when 11=> index0<="00000100"; --3 when 12=> index0<="00000010"; --2 when 13=> index0<="00000010"; --2 when 14=> index0<="00000001"; --1 when 15=> index0<="00000001"; --1 when 16=> index0<="00010000"; --5 when 17=> index0<="00010000"; --5 when 18=> index0<="00001000"; --4 when 19=> index0<="00001000"; --4 when 20=> index0<="00001000"; --4 when 21=> index0<="00000100"; --3 when 22=> index0<="00000010"; --2 when 23=> index0<="00000010"; --2 when 24=> index0<="00010000"; --5 when 25=> index0<="00010000"; --5 when 26=> index0<="00001000"; --4 when 27=> index0<="00001000"; --4 when 28=> index0<="00000100"; --3 when 29=> index0<="00000100"; --3 when 30=> index0<="00000010"; --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.18.5 自動演奏模塊仿真圖 (注:由于輸入頻率太高,實(shí)驗(yàn)條件所限,如按源程序仿真將看不到輸出波形,因此將原脈沖的分頻點(diǎn)4000000和8000000改為4和8,得到如圖的仿真結(jié)果,在實(shí)際燒制芯片中不作此處理。)
|