--------------------------------------------------------------------------- -- (c) 2013 mark watson -- I am happy for anyone to use this for non-commercial use. -- If my vhdl files are used commercially or otherwise sold, -- please contact me for explicit permission at scrameta (gmail). -- This applies for source and binary form and derived works. --------------------------------------------------------------------------- LIBRARY ieee; USE ieee.std_logic_1164.all; ENTITY i2sslave IS PORT ( CLK_HALF : IN STD_LOGIC; BCLK : IN STD_LOGIC; DACLRC : IN STD_LOGIC; LEFT_IN : in std_logic_vector(15 downto 0); RIGHT_IN : in std_logic_vector(15 downto 0); MCLK_2 : OUT STD_LOGIC; DACDAT : OUT STD_LOGIC ); END i2sslave; ARCHITECTURE vhdl OF i2sslave IS signal bclk_reg : std_logic; signal bclk_last_reg : std_logic; signal daclrc_reg : std_logic; signal daclrc_last_reg : std_logic; signal shiftreg_reg : std_logic_vector(15 downto 0); signal shiftreg_next : std_logic_vector(15 downto 0); BEGIN MCLK_2 <= CLK_HALF; -- bad practice, but pll out of... -- Data read on bclk low->high transition -- daclrc is set on bclk high->low transition -- register inputs process(CLK_HALF) begin if (CLK_HALF'event and CLK_HALF='1') then bclk_reg <= bclk; bclk_last_reg <= bclk_reg; daclrc_reg <= daclrc; daclrc_last_reg <= daclrc_reg; shiftreg_reg <= shiftreg_next; end if; end process; -- sample on change to daclrc, shift out bit if required process(daclrc_reg,daclrc_last_reg,bclk_reg,shiftreg_reg,left_in,right_in,bclk_last_reg) variable reload : std_logic; begin reload := '0'; shiftreg_next <= shiftreg_reg; if (daclrc_reg = '1' and daclrc_last_reg = '0') then shiftreg_next <= right_in; reload := '1'; end if; if (daclrc_reg = '0' and daclrc_last_reg = '1') then shiftreg_next <= left_in; reload := '1'; end if; if (bclk_reg = '0' and bclk_last_reg = '1' and reload='0') then shiftreg_next <= shiftreg_reg(14 downto 0)&'0'; end if; end process; DACDAT <= shiftreg_reg(15); END vhdl;