library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all; entity i2s_shifter is Port ( mclk : in std_logic; res : in std_logic; xti : in std_logic; xto : out std_logic; mclk_div : in std_logic_vector ( 1 downto 0); adr : in std_logic_vector ( 1 downto 0); data : in std_logic_vector ( 7 downto 0); dwen : in std_logic; new_smp : out std_logic; bclk_out : out std_logic; lrclk : out std_logic; sdout : out std_logic ); end i2s_shifter; architecture Behavioral of i2s_shifter is -- eingangsbuffer signal data_l_temp : std_logic_vector (11 downto 0); signal data_r_temp : std_logic_vector (11 downto 0); -- "schiebe-register" (eher muxer) signal data_l_buffer : std_logic_vector (11 downto 0); signal data_r_buffer : std_logic_vector (11 downto 0); signal bcnt : std_logic_vector ( 4 downto 0); -- master clock divider signal bdiv_cnt : std_logic_vector ( 2 downto 0); signal bclk : std_logic; begin -- quarz xto <= not xti; bclk_out <= bclk; process (mclk, bclk, res) begin if res = '1' then bdiv_cnt <= (others => '0'); elsif mclk'event and mclk = '1' then bdiv_cnt <= bdiv_cnt + '1'; end if; case mclk_div is when "00" => bclk <= not mclk; when "01" => bclk <= not bdiv_cnt (0); when "10" => bclk <= not bdiv_cnt (1); when "11" => bclk <= not bdiv_cnt (2); when others => NULL; end case; end process; process (bclk, res, data, adr, dwen) begin if res = '1' then data_l_temp <= (others => '0'); data_r_temp <= (others => '0'); elsif bclk'event and bclk = '1' then if dwen = '1' then case adr is when "00" => data_l_temp (11 downto 4) <= data; when "01" => data_l_temp ( 3 downto 0) <= data (7 downto 4); when "10" => data_r_temp (11 downto 4) <= data; when "11" => data_r_temp ( 3 downto 0) <= data (7 downto 4); when others => NULL; end case; end if; end if; end process; process (mclk, bclk, res, data_l_temp, data_r_temp, bcnt, data_l_buffer, data_r_buffer) begin if res = '1' then data_l_buffer <= (others => '0'); data_r_buffer <= (others => '0'); new_smp <= '0'; bcnt <= (others => '0'); elsif bclk'event and bclk= '0' then bcnt <= bcnt + '1'; if bcnt = "11111" then data_l_buffer <= data_l_temp; data_r_buffer <= data_r_temp; new_smp <= '1'; else new_smp <= '0'; end if; end if; end process; process (mclk, bclk, res, bcnt, data_l_buffer, data_r_buffer) begin case bcnt is when "00000" => sdout <= data_l_buffer (11); -- msb (als sign-extend when "00001" => sdout <= data_l_buffer (10); when "00010" => sdout <= data_l_buffer ( 9); when "00011" => sdout <= data_l_buffer ( 8); when "00100" => sdout <= data_l_buffer ( 7); when "00101" => sdout <= data_l_buffer ( 6); when "00110" => sdout <= data_l_buffer ( 5); when "00111" => sdout <= data_l_buffer ( 4); when "01000" => sdout <= data_l_buffer ( 3); when "01001" => sdout <= data_l_buffer ( 2); when "01010" => sdout <= data_l_buffer ( 1); when "01011" => sdout <= data_l_buffer ( 0); when "01100" => sdout <= '0'; when "01101" => sdout <= '0'; when "01110" => sdout <= '0'; when "01111" => sdout <= '0'; when "10000" => sdout <= data_r_buffer (11); -- msb (als sign-extend when "10001" => sdout <= data_r_buffer (10); when "10010" => sdout <= data_r_buffer ( 9); when "10011" => sdout <= data_r_buffer ( 8); when "10100" => sdout <= data_r_buffer ( 7); when "10101" => sdout <= data_r_buffer ( 6); when "10110" => sdout <= data_r_buffer ( 5); when "10111" => sdout <= data_r_buffer ( 4); when "11000" => sdout <= data_r_buffer ( 3); when "11001" => sdout <= data_r_buffer ( 2); when "11010" => sdout <= data_r_buffer ( 1); when "11011" => sdout <= data_r_buffer ( 0); when "11100" => sdout <= '0'; when "11101" => sdout <= '0'; when "11110" => sdout <= '0'; when "11111" => sdout <= '0'; when others => NULL; end case; end process; process (mclk, bclk, res, bcnt) begin case bcnt is when "00000" => lrclk <= '0'; when "00001" => lrclk <= '0'; when "00010" => lrclk <= '0'; when "00011" => lrclk <= '0'; when "00100" => lrclk <= '0'; when "00101" => lrclk <= '0'; when "00110" => lrclk <= '0'; when "00111" => lrclk <= '0'; when "01000" => lrclk <= '0'; when "01001" => lrclk <= '0'; when "01010" => lrclk <= '0'; when "01011" => lrclk <= '0'; when "01100" => lrclk <= '0'; when "01101" => lrclk <= '0'; when "01110" => lrclk <= '0'; when "01111" => lrclk <= '1'; when "10000" => lrclk <= '1'; when "10001" => lrclk <= '1'; when "10010" => lrclk <= '1'; when "10011" => lrclk <= '1'; when "10100" => lrclk <= '1'; when "10101" => lrclk <= '1'; when "10110" => lrclk <= '1'; when "10111" => lrclk <= '1'; when "11000" => lrclk <= '1'; when "11001" => lrclk <= '1'; when "11010" => lrclk <= '1'; when "11011" => lrclk <= '1'; when "11100" => lrclk <= '1'; when "11101" => lrclk <= '1'; when "11110" => lrclk <= '1'; when "11111" => lrclk <= '0'; when others => NULL; end case; end process; end Behavioral;