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