i2s_shifter.vhdl
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;