www.mikrocontroller.net

i2s_shifter.vhdl

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;

webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net