📄 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 + -