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

📄 player.vhd

📁 audio file on virtex
💻 VHD
字号:
-------------------------------------------------------------------------------
-- player.vhd
--
-- Author(s):     Jorgen Peddersen
-- Created:       Dec 2000
-- Last Modified: Dec 2000
-- 
-- Plays about 10 seconds of stereo output from the RAM into the stereo encoder.
-- When start is asserted, the player will keep playing until stop is
-- asserted or the end of RAM is reached.  If the end of RAM is reached, then
-- the output done is asserted.
-------------------------------------------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;

entity player is
    port (
        start: in STD_LOGIC;							-- assert to start playing
        stop: in STD_LOGIC;								-- assert to stop playing
        rstn: in STD_LOGIC;								-- asynchronous active low reset
        sclk: in STD_LOGIC;								-- sampling clock signal
        lrck: in STD_LOGIC;								-- left/right select clock
        dataIn: in STD_LOGIC_VECTOR (31 downto 0);		-- data from RAM
        address: out STD_LOGIC_VECTOR (18 downto 0);	-- address of RAM
        done: out STD_LOGIC;							-- indicates when RAM has been exhausted
        read: out STD_LOGIC;							-- read signal to RAM
        sdout: out STD_LOGIC							-- serial data to chip
    );
end player;

architecture player_arch of player is

--State signals
type STATETYPE is (stReset, stWait, stIdleL, stDataL, stIdleR, stDataR, stStop);

signal presState : STATETYPE;
signal nextState : STATETYPE;

signal addressInt : STD_LOGIC_VECTOR (18 downto 0);		-- internal address value
signal dataInt : STD_LOGIC_VECTOR (31 downto 0);		-- internal data value
signal incAddress : STD_LOGIC;							-- increment address
signal clrAddress : STD_LOGIC;							-- reset address to 0

signal latch : STD_LOGIC;								-- signal to latch data
signal shiftOut : STD_LOGIC;							-- signal to shift out data

signal dataCounter : STD_LOGIC_VECTOR (3 downto 0);		-- count how many shifts have occured
signal incData : STD_LOGIC;								-- increment data counter


begin

	process(sclk, rstn)
	begin
		if rstn = '0' then
			presState <= stReset;
			addressInt <= (others => '0');
			dataInt <= (others => '0');
			dataCounter <= (others => '0');
		elsif sclk'event and sclk = '0' then
			presState <= nextState;			-- go to next state
			
			-- handle RAM address and its signals
			if clrAddress = '1' then
				addressInt <= (others => '0');
			elsif incAddress = '1' then
				addressInt <= addressInt + 1;
			end if;
			
			-- latch data or shift it out MSB first
			if latch = '1' then
				dataInt <= dataIn;
			elsif shiftOut = '1' then
				dataInt <= dataInt(30 downto 0) & '0';
			end if;

			-- handle dataCounter, it automatically overflows at 16				
			if incData = '1' then
				dataCounter <= dataCounter + 1;
			end if;
			
		end if;
	end process;
	
	process(presState, LRCK, dataCounter, addressInt, dataInt, start, stop)
	begin
		-- default values of signals
		latch <= '0';
		shiftOut <= '0';
		clrAddress <= '0';
		incAddress <= '0';
		incData <= '0';
		read <= '0';
		done <= '0';
		sdout <= '0';
		
		case presState is
			when stReset =>
				-- wait for start button to be pushed
				if start = '0' then
					nextState <= stReset;
				else
					nextState <= stWait;
					clrAddress <= '1';	-- reset address
				end if;
			when stWait =>
				-- wait for right channel to be active
				if LRCK = '1' then
					nextState <= stWait;
				else
					-- read data to send and latch it
					nextState <= stIdleL;
					read <= '1';
					latch <= '1';
				end if;
			when stIdleL =>
				if LRCK = '0' then
					-- start playback when left channel becomes active				
					nextState <= stIdleL;
				else
					nextState <= stDataL;
					-- send first bit of data
					sdout <= dataInt(31);
					shiftOut <= '1';
					incData <= '1';
				end if;
			when stDataL =>
				-- send data until 16 bits are sent.			
				if dataCounter /= 0 then
					-- send data until counter overflows
					nextState <= stDataL;
					sdout <= dataInt(31);
					shiftOut <= '1';
					incData <= '1';
				else
					-- wait for right channel
					nextState <= stIdleR;
				end if;
			when stIdleR =>
				if LRCK = '1' then
					-- start playback when right channel becomes active
					nextState <= stIdleR;
				else
					-- send first bit of data
					nextState <= stDataR;
					sdout <= dataInt(31);
					shiftOut <= '1';
					incData <= '1';
				end if;					
			when stDataR =>
				-- send data until 16 bits are sent.
				if dataCounter /= 0 then
					-- send data until counter overflows
					nextState <= stDataR;
					sdout <= dataInt(31);
					shiftOut <= '1';
					incData <= '1';
				else
					-- go to next address
					nextState <= stStop;
					incAddress <= '1';
				end if;
			when stStop =>
				-- Check if playback should finish 
				if addressInt = 0 then
					-- address has overflowed so don't read any more data until start is asserted
					if start = '1' then
						nextState <= stWait;
					else
						nextState <= stStop;
						done <= '1';
					end if;
				elsif stop = '1' then
					-- if the stop signal is asserted then wait for the start signal
					nextState <= stReset;
				else
					-- There is more RAM left so keep playing
					nextState <= stIdleL;
					-- read next data from RAM
					read <= '1';
					latch <= '1';
				end if;
		end case;
	end process;		
	
	-- map internal signal to output	
	address <= addressInt;
	
end player_arch;

⌨️ 快捷键说明

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