📄 player.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 + -