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

📄 mpeg_chip_ctrl.vhd

📁 MP3 for XPLA3 XILINX.CPLD,必须在XILINX的FPGA芯片下使用,因为IP核是xilinx
💻 VHD
字号:
-- **************************************************************
-- File:  		mpeg_chip_ctrl.vhd
--
-- Purpose: 	This file implements the MPEG Chip Control circuit
--			that communicates with the I2C Master for configuring
--			the DAC3550A. This circuit performs the sequence of 
--			I2C commands necessary to write registers in the DAC3550A.
--			The MPEG Chip Control Logic interfaces to the Main State
--			Machine and the I2C Master Logic. The I2C commands are
--			encoded on the CMD bus as follows:
--
--			CMD		Command
--			---		-------
--			00		Do nothing
--			01		Write Status Register
--			10		Write Volume Register
--			11		Write Config Register
--
--			The signal CMD_DAT when writing to the volume register indicates
--			whether to adjust the volume (0) or mute the device (1). The signal
--			CMD_DAT when writing to the Config register indicates whether
--			to put the DAC3550A in low-power (1) or normal mode (0).
--
--			This logic consists of a state machine that sets the
--			start bit, paces the writing of data to the I2C Master Logic
--			and then ends the command.
--	
-- Created:		10/11/99	ALS
--
-- Revised:		10/14/99 	ALS			
-- Revised:		10/15/99	ALS
-- Revised:		11-14-99 	ALS
-- Revised:		11-28-99 	ALS
-- **************************************************************

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity mpeg_chip_ctrl is
  
  port(
	-- Main State Machine Interface Signals
	cmd 		: in 		std_logic_vector(1 downto 0); -- encoded command
	cmd_dat	: in		std_logic;	-- command mode (mute,vol or low-pwr,norm)
	mpeg_done	: out		std_logic;	-- I2C command completion
	err		: out		std_logic;  -- I2C or other error
	
	-- I2C Master Logic Interface Signals
	i2cd		: inout	std_logic_vector(7 downto 0);	-- I2C Data
	start		: out		std_logic;	-- start/stop indicator
	eot		: in		std_logic;	-- End of Byte Transfer
	i2c_err	: in		std_logic; 	-- error signal
	detect_stop : in		std_logic;	-- denotes that the transfer is stopped

	-- Volume Counter
	vol_lvl	: in		std_logic_vector(5 downto 0); -- volume level for both
										-- left and right speakers

	-- Mute Status
	mute_stat	: in		std_logic;	-- 1 = mute, 0 = return to previous volume

      clock		: in		std_logic;	-- 2 MHz system clock
	reset 	: in 		std_logic	-- system reset
);

end mpeg_chip_ctrl;

library IEEE;
use IEEE.std_logic_1164.all;

architecture behave of mpeg_chip_ctrl is

-- ******************** CONSTANT DECLARATIONS ***********************

-- DAC3550A Register Data Words
constant SR_REG_DATA	:	std_logic_vector(7 downto 0) := "00011111"; -- SR_REG data
constant GCFG_NORM	:	std_logic_vector(7 downto 0) := "00000100"; -- puts DAC in normal mode
constant GCFG_LOWPWR	:	std_logic_vector(7 downto 0) := "00100100"; -- puts DAC in low-pwr mode

constant DO_NOTHING	:	std_logic_vector(1 downto 0) := "00";	-- CMD bus value for do nothing
constant WR_SRREG		:	std_logic_vector(1 downto 0) := "01";	-- CMD bus value for write SR_REG
constant WR_AVOLREG	:	std_logic_vector(1 downto 0) := "10";	-- CMD bus value for write AVOL
constant WR_GCFGREG	:	std_logic_vector(1 downto 0) := "11";	-- CMD bus value for write GCFG

-- DAC3550A Dev Write command
constant DEV_WRITE	:     std_logic_vector (7 downto 0) := "10011010"; -- DEVWRITE

-- Reset Value
constant RESET_ACTIVE	: 	std_logic := '1';

-- ********************* SIGNAL DECLARATIONS ************************

type state_type is (IDLE, HEADER, SUBADDR, DATA_1, DATA_2, WAIT_STOP, DONE);
signal state, next_state : state_type;


signal i2c_data_com	: std_logic_vector(7 downto 0);	-- combinatorial I2C data
signal start_com		: std_logic;				-- combinatorial start signal
signal sm_err		: std_logic;				-- error from state machine

signal eot_d1		: std_logic;		-- sampled version of EOT for rising edge detect
signal eot_re		: std_logic;		-- EOT rising edge



begin

err <= i2c_err or sm_err;

-- ************************  MPEG Chip Control State Machine Process ************************
-- This process contains the combinatorial portion of the state machine
-- This state machine decodes the CMD bus and outputs the data for the command
mpeg_ctrl_comb: process (state, cmd, eot_re, i2c_err, cmd_dat, i2cd,
				mute_stat, vol_lvl, detect_stop)

begin

-- state machine defaults
	i2c_data_com <= i2cd;
	start_com <= '0';
	mpeg_done <= '0';
	next_state <= state;
	sm_err <= '0';

		case state is 
	
			--******************** IDLE State ******************
			when IDLE =>
				-- leave IDLE state if CMD contains a value

				if cmd /= DO_NOTHING then
					next_state <= HEADER;
				end if;

			--******************** HEADER State ******************
			when HEADER =>
				-- output header
				i2c_data_com <= DEV_WRITE;
				start_com <= '1';

				if eot_re = '1' then
					next_state <= SUBADDR;
				end if; 

			--******************** SUBADDR State ******************
			when SUBADDR =>
				start_com <= '1';
				
				-- set i2c data based on selected command
				-- 2 least significant bits of subaddress matches bits of CMD
				i2c_data_com <= "110000"& cmd;
			
				-- determine next state
				if eot_re = '1' then
					next_state <= DATA_1;
				end if;
				
			--******************** DATA_1 State ******************
			when DATA_1 =>
				start_com <= '1';
				
				-- based on the selected command, set the data for
				-- the I2C bus
				case cmd is

					when DO_NOTHING =>
						-- should not get to this state, set data to 0
						i2c_data_com <= (others => '0');
						sm_err <= '1';
					when WR_SRREG => 	-- write SR_REG
						i2c_data_com <= SR_REG_DATA;
					when WR_AVOLREG => 	-- write AVOL reg
						if mute_stat = '1' then
							-- mute dac by setting volume to 0
							i2c_data_com <= (others => '0');
						else
							-- set left volume back to volume level
							i2c_data_com <= "00" & vol_lvl;
						end if;

					when WR_GCFGREG =>
						if cmd_dat = '1' then
							i2c_data_com <= GCFG_LOWPWR;
						else
							i2c_data_com <= GCFG_NORM;
						end if;

					when others =>
						-- error
						sm_err <= '1';
						

				end case;

				-- determine next state
				if eot_re = '1' then 
					if cmd = WR_AVOLREG then
						-- EOT = 1
						-- command is to write AVOL register 
						-- this is 16 bits, write next data word
						next_state <= DATA_2;
					else
						-- EOT = 1, command is complete, wait
						-- detect STOP
						next_state <= WAIT_STOP;
					end if;
				end if;


			--******************** DATA_2 State ******************
			when DATA_2 =>
				start_com <= '1';
				-- write 2nd byte of AVOL register
				if cmd = WR_AVOLREG then
					if mute_stat = '1' then
						-- mute dac by setting volume to 0
						i2c_data_com <= (others => '0');
					else
						-- set right volume back to volume level
						i2c_data_com <= "00" & vol_lvl;
					end if;
				else
					-- command is not AVOL register, error
					-- no other command should have got to this state
					sm_err <= '1';
				end if;
	
				if eot_re = '1' then
					next_state <= WAIT_STOP;
				end if;


			-- ******************* WAIT_STOP State *************
			when WAIT_STOP =>
				-- START is negated in this state
				-- wait in this state for DETECT_STOP to assert
				-- when it asserts, move to DONE state
				if detect_stop = '1' then
					next_state <= DONE;
				end if;
				
			--******************** DONE State ******************
			when DONE =>
				mpeg_done <= '1';
				next_state <= IDLE;

			--******************** Default State ******************
			when others =>
					next_state <= IDLE;
	
		end case;
end process;

mpeg_chip_ctrl_regs: process (clock, reset, i2c_err)
begin
	if reset = RESET_ACTIVE or i2c_err = '1' then
		state <= IDLE;
		i2cd <= (others => '0');
		start <= '0';
	elsif clock'event and clock='1' then
		state <= next_state;
		i2cd <= i2c_data_com;
		start <= start_com;
	end if;
end process;

-- ************************  EOT Rising Edge Detect Process ************************
-- This process detects a rising edge on EOT

eot_re_proc: process(clock, reset)
begin
	if reset = RESET_ACTIVE then
		eot_d1 <= '0';
	elsif clock'event and clock = '1' then
		eot_d1 <= eot;
	end if;
end process;

eot_re <= '1' when (eot_d1 = '0' and eot = '1')
		  else '0';

		

end behave;

⌨️ 快捷键说明

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