📄 i2s_codec.vhd
字号:
----------------------------------------------------------------------
---- ----
---- WISHBONE I2S Interface IP Core ----
---- ----
---- This file is part of the I2S Interface project ----
---- http://www.opencores.org/cores/i2s_interface/ ----
---- ----
---- Description ----
---- I2S encoder/decoder. ----
---- ----
---- ----
---- To Do: ----
---- - ----
---- ----
---- Author(s): ----
---- - Geir Drange, gedra@opencores.org ----
---- ----
----------------------------------------------------------------------
---- ----
---- Copyright (C) 2004 Authors and OPENCORES.ORG ----
---- ----
---- This source file may be used and distributed without ----
---- restriction provided that this copyright statement is not ----
---- removed from the file and that any derivative work contains ----
---- the original copyright notice and the associated disclaimer. ----
---- ----
---- This source file is free software; you can redistribute it ----
---- and/or modify it under the terms of the GNU General ----
---- Public License as published by the Free Software Foundation; ----
---- either version 2.0 of the License, or (at your option) any ----
---- later version. ----
---- ----
---- This source is distributed in the hope that it will be ----
---- useful, but WITHOUT ANY WARRANTY; without even the implied ----
---- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ----
---- PURPOSE. See the GNU General Public License for more details.----
---- ----
---- You should have received a copy of the GNU General ----
---- Public License along with this source; if not, download it ----
---- from http://www.gnu.org/licenses/gpl.txt ----
---- ----
----------------------------------------------------------------------
--
-- CVS Revision History
--
-- $Log: i2s_codec.vhd,v $
-- Revision 1.3 2005/06/03 17:18:08 gedra
-- BugFix: LSB of transmitted word would be set to zero in slave master mode. (Credit: Julien Dumont)
--
-- Revision 1.2 2004/08/06 18:55:05 gedra
-- Removed conf_inten, and fixed bug in transmitter master mode.
--
-- Revision 1.1 2004/08/03 18:49:43 gedra
-- I2S encoder/decoder.
--
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity i2s_codec is
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer;
IS_MASTER: integer range 0 to 1;
IS_RECEIVER: integer range 0 to 1);
port (
wb_clk_i: in std_logic; -- wishbone clock
conf_res: in std_logic_vector(5 downto 0); -- sample resolution
conf_ratio: in std_logic_vector(7 downto 0); -- clock divider ratio
conf_swap: in std_logic; -- left/right sample order
conf_en: in std_logic; -- transmitter/recevier enable
i2s_sd_i: in std_logic; -- I2S serial data input
i2s_sck_i: in std_logic; -- I2S clock input
i2s_ws_i: in std_logic; -- I2S word select input
sample_dat_i: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data
sample_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- audio data
mem_rdwr: out std_logic; -- sample buffer read/write
sample_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0); -- address
evt_hsbf: out std_logic; -- higher sample buf empty event
evt_lsbf: out std_logic; -- lower sample buf empty event
i2s_sd_o: out std_logic; -- I2S serial data output
i2s_sck_o: out std_logic; -- I2S clock output
i2s_ws_o: out std_logic); -- I2S word select output
end i2s_codec;
architecture rtl of i2s_codec is
signal i2s_clk_en, zsck, zzsck, zzzsck, imem_rd : std_logic;
signal clk_cnt : integer range 0 to 255;
signal adr_cnt : integer range 0 to 2**(ADDR_WIDTH - 1) - 1;
type srx_states is (IDLE, WAIT_CLK, TRX_DATA, RX_WRITE, SYNC);
signal sd_ctrl : srx_states;
signal bit_cnt, bits_to_trx : integer range 0 to 63;
signal toggle, master, neg_edge, ws_pos_edge, ws_neg_edge : std_logic;
signal data_in : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal zws, zzws, zzzws, i2s_ws, new_word, last_bit: std_logic;
signal imem_rdwr, receiver : std_logic;
signal ws_cnt : integer range 0 to 31;
begin
-- Create signals that reflect generics
SGM: if IS_MASTER = 1 generate
master <= '1';
end generate SGM;
SGS: if IS_MASTER = 0 generate
master <= '0';
end generate SGS;
SGRX: if IS_RECEIVER = 1 generate
receiver <= '1';
end generate SGRX;
SGTX: if IS_RECEIVER = 0 generate
receiver <= '0';
end generate SGTX;
-- I2S clock enable generation, master mode. The clock is a fraction of the
-- Wishbone bus clock, determined by the conf_ratio value.
CGM: if IS_MASTER = 1 generate
CGEN: process (wb_clk_i)
begin
if rising_edge(wb_clk_i) then
if conf_en = '0' then -- disabled
i2s_clk_en <= '0';
clk_cnt <= 0;
neg_edge <= '0';
toggle <= '0';
else -- enabled
if clk_cnt < to_integer(unsigned(conf_ratio)) + 1 then
clk_cnt <= (clk_cnt + 1) mod 256;
i2s_clk_en <= '0';
else
clk_cnt <= 0;
i2s_clk_en <= '1';
neg_edge <= not neg_edge;
end if;
toggle <= neg_edge;
end if;
end if;
end process CGEN;
end generate CGM;
-- I2S clock enable generation, slave mode. The input clock signal is sampeled
-- and the negative edge is located.
CGS: if IS_MASTER = 0 generate
CGEN: process (wb_clk_i)
begin
if rising_edge(wb_clk_i) then
if conf_en = '0' then -- disabled
i2s_clk_en <= '0';
zsck <= '0';
zzsck <= '0';
zzzsck <= '0';
toggle <= '0';
neg_edge <= '0';
else -- enabled
-- synchronize input clock to Wishbone clock domaine
zsck <= i2s_sck_i;
zzsck <= zsck;
zzzsck <= zzsck;
-- look for edges
if zzzsck = '1' and zzsck = '0' then
i2s_clk_en <= '1';
neg_edge <= '1';
elsif zzzsck = '0' and zzsck = '1' then
i2s_clk_en <= '1';
neg_edge <= '0';
else
i2s_clk_en <= '0';
end if;
toggle <= neg_edge;
end if;
end if;
end process CGEN;
end generate CGS;
-- Process to generate word select signal, master mode
WSM: if IS_MASTER = 1 generate
i2s_ws_o <= i2s_ws;
WSG: process (wb_clk_i)
begin
if rising_edge(wb_clk_i) then
if conf_en = '0' then
i2s_ws <= '0';
ws_cnt <= 0;
ws_pos_edge <= '0';
ws_neg_edge <= '0';
else
if i2s_clk_en = '1' and toggle = '1' then
if ws_cnt < bits_to_trx then
ws_cnt <= ws_cnt + 1;
else
i2s_ws <= not i2s_ws;
ws_cnt <= 0;
if i2s_ws = '1' then
ws_neg_edge <= '1';
else
ws_pos_edge <= '1';
end if;
end if;
else
ws_pos_edge <= '0';
ws_neg_edge <= '0';
end if;
end if;
end if;
end process WSG;
end generate WSM;
-- Process to detect word select edges, slave mode
WSD: if IS_MASTER = 0 generate
i2s_ws <= i2s_ws_i;
WSDET: process (wb_clk_i)
begin
if rising_edge(wb_clk_i) then
if conf_en = '0' then
ws_pos_edge <= '0';
ws_neg_edge <= '0';
zws <= i2s_ws;
zzws <= i2s_ws;
zzzws <= i2s_ws;
else
-- sync i2s_ws_io to our clock domaine
zws <= i2s_ws;
zzws <= zws;
zzzws <= zzws;
-- detect negative edge
if zzzws = '1' and zzws = '0' then
ws_neg_edge <= '1';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -