⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 play_ram.vhd

📁 多功能电子琴 可以实现人性化界面 同时可以根据按键选择播放模式
💻 VHD
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.ram_pack.all;

package rom_pack is
	subtype rom_word is integer;
	subtype rom_range1 is integer range 0 to 48;
	subtype rom_range2 is integer range 0 to 60;
	type rom_type1 is array(rom_range1) of rom_word;
	type rom_type2 is array(rom_range2) of rom_word;
	constant rom1_tune:rom_type1:=(
			5,8,8,5,8,9,10,11,12,0,
			8,15,14,0,14,15,14,13,14,12,10,12,0,
			8,11,12,13,0,13,14,15,16,17,12,0,
			5,8,12,11,0,11,10,9,8,16,14,15,0,30     
			
			);
     constant rom1_time:rom_type1:=(
			8,16,8,8,8,8,8,8,24,8,
			8,8,24,1,8,8,8,16,8,4,4,16,8,
			8,8,8,8,8,8,8,8,8,8,16,8,
			8,8,8,16,2,8,8,8,8,16,8,24,20,10

			);
     constant rom2_tune:rom_type2:=(
			(5),(8),(8),(8),(10),(9),(8),(9),(10),(8),(8),(10),(12),
			(13),(0),(13),(12),(10),(10),(8),(9),(8),(9),(10),(8),(6),
			(6),(5),(8),(0),(13),(12),(10),(10),(8),(9),(8),(9),(13),
			(12),(10),(10),(12),(13),(0),(13),(12),(10),(10),(8),(9),
			(8),(9),(10),(8),(6),(6),(5),(8),(0),(30));
     constant rom2_time:rom_type2:=(
			(8),(8),(4),(8),(8),(12),(4),(8),(8),(12),(4),(8),(8),
			(24),(2),(8),(12),(4),(8),(8),(12),(4),(8),(8),(12),(4),
			(8),(8),(24),(2),(8),(12),(4),(8),(8),(12),(4),(8),(8),
			(12),(4),(8),(8),(24),(2),(8),(12),(4),(8),(8),(12),(4),
			(8),(8),(12),(4),(8),(8),(32),(20),(10));
end rom_pack;

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
use work.ram_pack.all;
use work.rom_pack.all;

entity Play_ram is
	port(
		keynum2 : in integer range 0 to 31;
		signal tune_played : RAM_TYPE;
		signal time_passed : RAM_TYPE;
		max_addr : in integer range 0 to 127;
		Ctrl:in std_logic_vector(2 downto 0);
		song : out std_logic;
		clk_com,clk_in,choose: in std_logic;
		Dout:out std_logic_vector(6 downto 0);	--数码管数据信号
		Leds:out std_logic_vector(5 downto 0);	--数码管选通信号
		Key_Leds:out std_logic_vector(7 downto 0)	--输出音阶的LED显示
		);
end Play_ram;

architecture code of Play_ram is
signal temp,temp1,temp2,count,count1,count2 : integer range 0 to 1023;
signal freq : integer range 0 to 31;
signal mark_0:std_logic;--在已有音符之间播放时插播0
signal stop:std_logic;--ram中音符放完之后停止标志
component div_freq
	port(
		tune : in integer;
		clk  : in std_logic;
		output : out std_logic
		);
end component;

component State is
	port(
		Clk_20M:in std_logic;	--20M时钟,用于分频
		Ctrl:in std_logic_vector(2 downto 0);	--模式选择控制,用S1拨盘实现
		Tone:in integer range 0 to 21;  --音符
	    Dout:out std_logic_vector(6 downto 0);	--数码管数据信号
		Leds:out std_logic_vector(5 downto 0);	--数码管选通信号
		Key_Leds:out std_logic_vector(7 downto 0)	--输出音阶的LED显示
		);
end component;

begin
	u1:div_freq port map(freq,clk_com,song);
	u2:State port map(clk_com,Ctrl,freq,Dout,Leds,Key_Leds);
	process(keynum2,clk_in,tune_played,Ctrl,time_passed,max_addr,choose)
	begin
		if clk_in'event and clk_in='1' then
			case Ctrl(1 downto 0) is
				when "10" =>
					if stop='0' then
						if mark_0='0' then 
							freq<=tune_played(temp);
							if temp>max_addr then
								freq<=0;
								stop<='1';
							end if;
							count<=count + 1;
							if count=time_passed(temp) then
								temp<=temp+1;
								count<=0 ;
								mark_0<='1';
							end if;	
						else
							freq<=0;
							count<=count+1;
							if count=5 then
								count<=0;
								mark_0<='0';
							end if;
						end if;	
					else 
						null;
					end if;					
				when "01" => freq<=keynum2;
							 stop<='0';
				when "00" => temp<=0;count<=0;
							 stop<='0';
							case Ctrl(2) is
								when '1' => case choose is
												when '1' => temp2<=0;count2<=0;
															freq<=rom1_tune(temp1);
															if freq=30 then
																temp1<=0;
															end if;
															count1<=count1 + 1;
															if count1=rom1_time(temp1) then
																temp1<=temp1+1;count1<=0 ;
															end if;
												when '0' => temp1<=0;count1<=0;
															freq<=rom2_tune(temp2);
															if freq=30 then
																temp2<=0;
															end if;
															count2<=count2 + 1;
															if count2=rom2_time(temp2) then
																temp2<=temp2+1;count2<=0 ;
															end if;
											end case;
								when '0' => freq<=0;
							end case;
				when others => stop<='0';
			end case;
		end if;
	end process;
end code;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -