📄 i2s_codec.vhd
字号:
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 + -