⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2s_codec.vhd

📁 这是一个I2S接口的VHDL实现源代码
💻 VHD
📖 第 1 页 / 共 2 页
字号:
          else
            ws_neg_edge <= '0';
          end if;
          -- detect positive edge
          if zzzws = '0' and zzws = '1' then
            ws_pos_edge <= '1';
          else
            ws_pos_edge <= '0';
          end if;
        end if;
      end if;
    end process WSDET;
  end generate WSD;

-- Logic to generate clock signal, master mode
  SCKM: if IS_MASTER = 1 generate
    i2s_sck_o <= toggle;
  end generate SCKM;
  
-- Process to receive data on i2s_sd_i, or transmit data on i2s_sd_o
  sample_addr <= std_logic_vector(to_unsigned(adr_cnt, ADDR_WIDTH - 1));
  mem_rdwr <= imem_rdwr;
  sample_dat_o <= data_in;
  
  SDRX: process (wb_clk_i)
  begin 
    if rising_edge(wb_clk_i) then
      if conf_en = '0' then           -- codec disabled
        imem_rdwr <= '0';
        sd_ctrl <= IDLE;
        data_in <= (others => '0');
        bit_cnt <= 0;
        bits_to_trx <= 0;
        new_word <= '0';
        last_bit <= '0';
        adr_cnt <= 0;
        evt_lsbf <= '0';
        evt_hsbf <= '0';
        i2s_sd_o <= '0';
      else
        case sd_ctrl is
          when IDLE =>
            imem_rdwr <= '0';
            if to_integer(unsigned(conf_res)) > 15 and
              to_integer(unsigned(conf_res)) < 33 then
              bits_to_trx <= to_integer(unsigned(conf_res)) - 1;
            else
              bits_to_trx <= 15;
            end if;
            if conf_en = '1' then
              if (ws_pos_edge = '1' and conf_swap = '1') or
                (ws_neg_edge = '1' and conf_swap = '0') then
                if receiver = '1' then    -- recevier
                  sd_ctrl <= WAIT_CLK;
                else
                  imem_rdwr <= '1';       -- read first data if transmitter
                  sd_ctrl <= TRX_DATA;
                end if;  
              end if;
            end if;
          when WAIT_CLK =>              -- wait for first bit after WS
            adr_cnt <= 0;
            bit_cnt <= 0;
            new_word <= '0';
            last_bit <= '0';
            data_in <= (others => '0');
            if i2s_clk_en = '1' and neg_edge = '0' then
              sd_ctrl <= TRX_DATA;
            end if;
          when TRX_DATA =>              -- transmit/receive serial data 
            imem_rdwr <= '0';
            evt_hsbf <= '0';
            evt_lsbf <= '0';
            if master = '0' then
              if zzzws /= zzws then
                new_word <= '1';
              end if;
            else
              if ws_pos_edge = '1' or ws_neg_edge = '1' then
                new_word <= '1';
              end if;
            end if;
            if new_word = '1' and i2s_clk_en = '1' and neg_edge = '0' then
              last_bit <= '1';
            end if;
            -- recevier operation
            if receiver = '1' then
              if i2s_clk_en = '1' and neg_edge = '1' then
                if master = '1' then    -- master mode
                  if bit_cnt < bits_to_trx and new_word = '0' then
                    bit_cnt <= bit_cnt + 1;
                    data_in(bits_to_trx - bit_cnt) <= i2s_sd_i;
                  else
                    imem_rdwr <= '1';
                    data_in(bits_to_trx - bit_cnt) <= i2s_sd_i;
                    sd_ctrl <= RX_WRITE;
                  end if;
                else                    -- slave mode
                  if bit_cnt <= bits_to_trx and new_word = '0' then
                    bit_cnt <= bit_cnt + 1;
                    data_in(bits_to_trx - bit_cnt) <= i2s_sd_i;
                  else
                    imem_rdwr <= '1';
                    sd_ctrl <= RX_WRITE;
                  end if;
                end if;
              end if;
            end if;
            -- transmitter operation
            if receiver = '0' then
              if master = '1' then      -- master mode
                if i2s_clk_en = '1' and neg_edge = '0' then
                  if bit_cnt < bits_to_trx and new_word = '0' then
                    bit_cnt <= bit_cnt + 1;
                    i2s_sd_o <= sample_dat_i(bits_to_trx - bit_cnt);
                  else
                    bit_cnt <= bit_cnt + 1;
                    if bit_cnt > bits_to_trx then
                      i2s_sd_o <= '0';
                    else
                      i2s_sd_o <= sample_dat_i(0);
                    end if;
                    -- transmitter address counter
                    imem_rdwr <= '1';
                    adr_cnt <= (adr_cnt + 1) mod 2**(ADDR_WIDTH - 1);
                    if adr_cnt = 2**(ADDR_WIDTH - 2) - 1 then
                      evt_lsbf <= '1';
                    else
                      evt_lsbf <= '0';
                    end if;
                    if adr_cnt = 2**(ADDR_WIDTH - 1) - 1 then
                      evt_hsbf <= '1';
                    else
                      evt_hsbf <= '0';
                    end if;
                    sd_ctrl <= SYNC;
                  end if; 
                end if;
              else                     -- slave mode
                if i2s_clk_en = '1' and neg_edge = '1' then
                  if bit_cnt < bits_to_trx and new_word = '0' then
                    bit_cnt <= bit_cnt + 1;
                    i2s_sd_o <= sample_dat_i(bits_to_trx - bit_cnt);
                  else
                    bit_cnt <= bit_cnt + 1;
                    if bit_cnt > bits_to_trx then
                      i2s_sd_o <= '0';
                    else
                      i2s_sd_o <= sample_dat_i(bits_to_trx - bit_cnt);
                    end if;
                    if new_word = '1' then  -- transmitter address counter
                      imem_rdwr <= '1';
                      adr_cnt <= (adr_cnt + 1) mod 2**(ADDR_WIDTH - 1);
                      if adr_cnt = 2**(ADDR_WIDTH - 2) - 1 then
                        evt_lsbf <= '1';
                      else
                        evt_lsbf <= '0';
                      end if;
                      if adr_cnt = 2**(ADDR_WIDTH - 1) - 1 then
                        evt_hsbf <= '1';
                      else
                        evt_hsbf <= '0';
                      end if;
                      sd_ctrl <= SYNC;
                    end if;
                  end if; 
                end if;
              end if;
            end if;
          when RX_WRITE =>             -- write received word to sample buffer
            imem_rdwr <= '0';
            adr_cnt <= (adr_cnt + 1) mod 2**(ADDR_WIDTH - 1);
            if adr_cnt = 2**(ADDR_WIDTH - 2) - 1 then
              evt_lsbf <= '1';
            else
              evt_lsbf <= '0';
            end if;
            if adr_cnt = 2**(ADDR_WIDTH - 1) - 1 then
              evt_hsbf <= '1';
            else
              evt_hsbf <= '0';
            end if;
            sd_ctrl <= SYNC;
          when SYNC =>                  -- synchronise with next word
            imem_rdwr <= '0';
            evt_hsbf <= '0';
            evt_lsbf <= '0';
            bit_cnt <= 0;
            if ws_pos_edge = '1' or ws_neg_edge = '1' then
              new_word <= '1';
            end if;
            if new_word = '1' and i2s_clk_en = '1' and neg_edge = '0' then
              last_bit <= '1';
            end if;
            if receiver = '1' then      -- receive mode
              if master = '1' then
                new_word <= '0';
                last_bit <= '0';
                data_in <= (others => '0');
                sd_ctrl <= TRX_DATA;
              else
                if i2s_clk_en = '1' and neg_edge = '0' and new_word = '1' then
                  new_word <= '0';
                  last_bit <= '0';
                  data_in <= (others => '0');
                  sd_ctrl <= TRX_DATA;
                end if;
              end if;
            else                        -- transmit mode
              if master = '1' then
                new_word <= '0';
                last_bit <= '0';
                data_in <= (others => '0');
                sd_ctrl <= TRX_DATA;
              elsif i2s_clk_en = '1' and neg_edge = '0' then
                new_word <= '0';
                last_bit <= '0';
                data_in <= (others => '0');
                sd_ctrl <= TRX_DATA;
              end if;
            end if;
          when others => null;
        end case;
      end if;
    end if;
  end process SDRX;
 
end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -