OpenCores
URL https://opencores.org/ocsvn/i2s_interface/i2s_interface/trunk

Subversion Repositories i2s_interface

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 23 to Rev 24
    Reverse comparison

Rev 23 → Rev 24

/trunk/rtl/vhdl/i2s_version.vhd
44,6 → 44,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
-- Revision 1.1 2004/08/03 18:49:03 gedra
-- Version register.
--
51,36 → 54,36
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity i2s_version is
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer;
IS_MASTER: integer);
port (
ver_rd: in std_logic; -- version register read
ver_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0)); -- reg. contents
entity i2s_version is
generic (DATA_WIDTH : integer;
ADDR_WIDTH : integer;
IS_MASTER : integer);
port (
ver_rd : in std_logic; -- version register read
ver_dout : out std_logic_vector(DATA_WIDTH - 1 downto 0)); -- reg. contents
end i2s_version;
 
architecture rtl of i2s_version is
 
signal version : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version : std_logic_vector(DATA_WIDTH - 1 downto 0);
 
begin
ver_dout <= version when ver_rd = '1' else (others => '0');
ver_dout <= version when ver_rd = '1' else (others => '0');
 
-- version vector generation
version(3 downto 0) <= "0001"; -- version 1
G32: if DATA_WIDTH = 32 generate
version(4) <= '1';
version(31 downto 16) <= (others => '0');
end generate G32;
G16: if DATA_WIDTH = 16 generate
version(4) <= '0';
end generate G16;
version(15 downto 13) <= (others => '0');
version(12 downto 6) <= std_logic_vector(to_unsigned(ADDR_WIDTH, 7));
version(5) <= '1' when IS_MASTER = 1 else '0';
-- version vector generation
version(3 downto 0) <= "0001"; -- version 1
G32 : if DATA_WIDTH = 32 generate
version(4) <= '1';
version(31 downto 16) <= (others => '0');
end generate G32;
G16 : if DATA_WIDTH = 16 generate
version(4) <= '0';
end generate G16;
version(15 downto 13) <= (others => '0');
version(12 downto 6) <= std_logic_vector(to_unsigned(ADDR_WIDTH, 7));
version(5) <= '1' when IS_MASTER = 1 else '0';
end rtl;
/trunk/rtl/vhdl/rx_i2s_wbd.vhd
43,6 → 43,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.3 2005/01/17 17:26:47 gedra
-- Bugfix of register read/write strobes
--
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
56,160 → 59,160
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity rx_i2s_wbd is
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer);
port (
wb_clk_i: in std_logic; -- wishbone clock
wb_rst_i: in std_logic; -- reset signal
wb_sel_i: in std_logic; -- select input
wb_stb_i: in std_logic; -- strobe input
wb_we_i: in std_logic; -- write enable
wb_cyc_i: in std_logic; -- cycle input
wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o: out std_logic; -- acknowledge
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd: out std_logic; -- Version register read
config_rd: out std_logic; -- Config register read
config_wr: out std_logic; -- Config register write
intmask_rd: out std_logic; -- Interrupt mask register read
intmask_wr: out std_logic; -- Interrupt mask register write
intstat_rd: out std_logic; -- Interrupt status register read
intstat_wr: out std_logic; -- Interrupt status register read
mem_rd: out std_logic; -- Sample memory read
mem_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0)); -- memory addr.
entity rx_i2s_wbd is
generic (DATA_WIDTH : integer;
ADDR_WIDTH : integer);
port (
wb_clk_i : in std_logic; -- wishbone clock
wb_rst_i : in std_logic; -- reset signal
wb_sel_i : in std_logic; -- select input
wb_stb_i : in std_logic; -- strobe input
wb_we_i : in std_logic; -- write enable
wb_cyc_i : in std_logic; -- cycle input
wb_bte_i : in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i : in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o : out std_logic; -- acknowledge
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd : out std_logic; -- Version register read
config_rd : out std_logic; -- Config register read
config_wr : out std_logic; -- Config register write
intmask_rd : out std_logic; -- Interrupt mask register read
intmask_wr : out std_logic; -- Interrupt mask register write
intstat_rd : out std_logic; -- Interrupt status register read
intstat_wr : out std_logic; -- Interrupt status register read
mem_rd : out std_logic; -- Sample memory read
mem_addr : out std_logic_vector(ADDR_WIDTH - 2 downto 0)); -- memory addr.
end rx_i2s_wbd;
 
architecture rtl of rx_i2s_wbd is
constant REG_RXVERSION : std_logic_vector(3 downto 0) := "0000";
constant REG_RXCONFIG : std_logic_vector(3 downto 0) := "0001";
constant REG_RXINTMASK : std_logic_vector(3 downto 0) := "0010";
constant REG_RXINTSTAT : std_logic_vector(3 downto 0) := "0011";
signal iack, iwr, ird : std_logic;
signal acnt: integer range 0 to 2**(ADDR_WIDTH - 1) - 1;
signal all_ones : std_logic_vector(ADDR_WIDTH - 1 downto 0);
signal rdout : std_logic_vector(DATA_WIDTH - 1 downto 0);
begin
constant REG_RXVERSION : std_logic_vector(3 downto 0) := "0000";
constant REG_RXCONFIG : std_logic_vector(3 downto 0) := "0001";
constant REG_RXINTMASK : std_logic_vector(3 downto 0) := "0010";
constant REG_RXINTSTAT : std_logic_vector(3 downto 0) := "0011";
signal iack, iwr, ird : std_logic;
signal acnt : integer range 0 to 2**(ADDR_WIDTH - 1) - 1;
signal all_ones : std_logic_vector(ADDR_WIDTH - 1 downto 0);
signal rdout : std_logic_vector(DATA_WIDTH - 1 downto 0);
begin
 
wb_ack_o <= iack;
wb_ack_o <= iack;
 
-- acknowledge generation
ACK: process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iack <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iack <= '1';
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
when "111" => -- end of burst
iack <= not iack;
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
else
iack <= '0';
end if;
end if;
end process ACK;
ACK : process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iack <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iack <= '1';
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
when "111" => -- end of burst
iack <= not iack;
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
else
iack <= '0';
end if;
end if;
end process ACK;
 
-- write generation
WR: process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iwr <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iwr <= '1';
when others => -- all other treated assert classic cycle
iwr <= not iwr;
end case;
when "111" => -- end of burst
iwr <= not iwr;
when others => -- all other treated assert classic cycle
iwr <= not iwr;
end case;
else
iwr <= '0';
end if;
end if;
end process WR;
WR : process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iwr <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iwr <= '1';
when others => -- all other treated assert classic cycle
iwr <= not iwr;
end case;
when "111" => -- end of burst
iwr <= not iwr;
when others => -- all other treated assert classic cycle
iwr <= not iwr;
end case;
else
iwr <= '0';
end if;
end if;
end process WR;
 
-- read generation
ird <= '1' when wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '0' else '0';
ird <= '1' when wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '0' else '0';
 
wb_dat_o <= data_out when wb_adr_i(ADDR_WIDTH - 1) = '1' else rdout;
wb_dat_o <= data_out when wb_adr_i(ADDR_WIDTH - 1) = '1' else rdout;
 
DREG: process (wb_clk_i) -- clock data from registers
begin
if rising_edge(wb_clk_i) then
rdout <= data_out;
end if;
end process DREG;
DREG : process (wb_clk_i) -- clock data from registers
begin
if rising_edge(wb_clk_i) then
rdout <= data_out;
end if;
end process DREG;
 
-- sample memory read address. This needs special attention due to read latency
mem_addr <= std_logic_vector(to_unsigned(acnt, ADDR_WIDTH - 1)) when
wb_cti_i = "010" and wb_we_i = '0' and iack = '1' and
wb_bte_i = "00" else wb_adr_i(ADDR_WIDTH - 2 downto 0);
all_ones(ADDR_WIDTH - 1 downto 0) <= (others => '1');
SMA: process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
acnt <= 0;
elsif rising_edge(wb_clk_i) then
if wb_cti_i = "010" and wb_we_i = '0' and wb_bte_i = "00" then
if iack = '0' then
if wb_adr_i = all_ones then
acnt <= 0;
else
acnt <= to_integer(unsigned(wb_adr_i)) + 1;
end if;
else
if acnt < 2**(ADDR_WIDTH - 1) - 1 then
acnt <= acnt + 1;
else
acnt <= 0;
end if;
end if;
mem_addr <= std_logic_vector(to_unsigned(acnt, ADDR_WIDTH - 1)) when
wb_cti_i = "010" and wb_we_i = '0' and iack = '1' and
wb_bte_i = "00" else wb_adr_i(ADDR_WIDTH - 2 downto 0);
all_ones(ADDR_WIDTH - 1 downto 0) <= (others => '1');
 
SMA : process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
acnt <= 0;
elsif rising_edge(wb_clk_i) then
if wb_cti_i = "010" and wb_we_i = '0' and wb_bte_i = "00" then
if iack = '0' then
if wb_adr_i = all_ones then
acnt <= 0;
else
acnt <= to_integer(unsigned(wb_adr_i)) + 1;
end if;
else
if acnt < 2**(ADDR_WIDTH - 1) - 1 then
acnt <= acnt + 1;
else
acnt <= 0;
end if;
end if;
end if;
end if;
end if;
end process SMA;
end process SMA;
 
-- read and write strobe generation
version_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXVERSION and ird = '1'
 
version_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXVERSION and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
config_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXCONFIG and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
config_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXCONFIG and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
config_wr <= '1' when wb_adr_i(3 downto 0) = REG_RXCONFIG and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intmask_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXINTMASK and ird = '1'
config_wr <= '1' when wb_adr_i(3 downto 0) = REG_RXCONFIG and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intmask_wr <= '1' when wb_adr_i(3 downto 0) = REG_RXINTMASK and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXINTSTAT and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_wr <= '1' when wb_adr_i(3 downto 0) = REG_RXINTSTAT and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
mem_rd <= '1' when wb_adr_i(ADDR_WIDTH - 1) = '1' and ird = '1' else '0';
intmask_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXINTMASK and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intmask_wr <= '1' when wb_adr_i(3 downto 0) = REG_RXINTMASK and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_rd <= '1' when wb_adr_i(3 downto 0) = REG_RXINTSTAT and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_wr <= '1' when wb_adr_i(3 downto 0) = REG_RXINTSTAT and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
mem_rd <= '1' when wb_adr_i(ADDR_WIDTH - 1) = '1' and ird = '1' else '0';
end rtl;
/trunk/rtl/vhdl/rx_i2s_pack.vhd
43,121 → 43,124
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
-- Revision 1.1 2004/08/04 14:28:54 gedra
-- Receiver component declarations.
--
--
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
 
package rx_i2s_pack is
 
-- components used in the receiver
component gen_control_reg
generic (DATA_WIDTH: integer;
-- note that this vector is (0 to xx), reverse order
ACTIVE_BIT_MASK: std_logic_vector);
port (
clk: in std_logic; -- clock
rst: in std_logic; -- reset
ctrl_wr: in std_logic; -- control register write
ctrl_rd: in std_logic; -- control register read
ctrl_din: in std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_bits: out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
component gen_control_reg
generic (DATA_WIDTH : integer;
-- note that this vector is (0 to xx), reverse order
ACTIVE_BIT_MASK : std_logic_vector);
port (
clk : in std_logic; -- clock
rst : in std_logic; -- reset
ctrl_wr : in std_logic; -- control register write
ctrl_rd : in std_logic; -- control register read
ctrl_din : in std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_dout : out std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_bits : out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
 
component gen_event_reg
generic (DATA_WIDTH: integer);
port (
clk: in std_logic; -- clock
rst: in std_logic; -- reset
evt_wr: in std_logic; -- event register write
evt_rd: in std_logic; -- event register read
evt_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data
event: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- event vector
evt_mask: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- irq mask
evt_en: in std_logic; -- irq enable
evt_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data
evt_irq: out std_logic); -- interrupt request
end component;
component gen_event_reg
generic (DATA_WIDTH : integer);
port (
clk : in std_logic; -- clock
rst : in std_logic; -- reset
evt_wr : in std_logic; -- event register write
evt_rd : in std_logic; -- event register read
evt_din : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data
event : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- event vector
evt_mask : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- irq mask
evt_en : in std_logic; -- irq enable
evt_dout : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data
evt_irq : out std_logic); -- interrupt request
end component;
 
component dpram
generic (DATA_WIDTH: positive;
RAM_WIDTH: positive);
port (
clk: in std_logic;
rst: in std_logic; -- reset is optional, not used here
din: in std_logic_vector(DATA_WIDTH - 1 downto 0);
wr_en: in std_logic;
rd_en: in std_logic;
wr_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0);
rd_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0);
dout: out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
component dpram
generic (DATA_WIDTH : positive;
RAM_WIDTH : positive);
port (
clk : in std_logic;
rst : in std_logic; -- reset is optional, not used here
din : in std_logic_vector(DATA_WIDTH - 1 downto 0);
wr_en : in std_logic;
rd_en : in std_logic;
wr_addr : in std_logic_vector(RAM_WIDTH - 1 downto 0);
rd_addr : in std_logic_vector(RAM_WIDTH - 1 downto 0);
dout : out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
 
component i2s_version
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer;
IS_MASTER: integer);
port (
ver_rd: in std_logic; -- version register read
ver_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
component i2s_version
generic (DATA_WIDTH : integer;
ADDR_WIDTH : integer;
IS_MASTER : integer);
port (
ver_rd : in std_logic; -- version register read
ver_dout : out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
 
component rx_i2s_wbd
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer);
port (
wb_clk_i: in std_logic; -- wishbone clock
wb_rst_i: in std_logic; -- reset signal
wb_sel_i: in std_logic; -- select input
wb_stb_i: in std_logic; -- strobe input
wb_we_i: in std_logic; -- write enable
wb_cyc_i: in std_logic; -- cycle input
wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o: out std_logic; -- acknowledge
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd: out std_logic; -- Version register read
config_rd: out std_logic; -- Config register read
config_wr: out std_logic; -- Config register write
intmask_rd: out std_logic; -- Interrupt mask register read
intmask_wr: out std_logic; -- Interrupt mask register write
intstat_rd: out std_logic; -- Interrupt status register read
intstat_wr: out std_logic; -- Interrupt status register read
mem_rd: out std_logic; -- Sample memory write
mem_addr: out std_logic_vector(ADDR_WIDTH - 2 downto 0)); -- memory addr.
end component;
component i2s_codec
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 component;
component rx_i2s_wbd
generic (DATA_WIDTH : integer;
ADDR_WIDTH : integer);
port (
wb_clk_i : in std_logic; -- wishbone clock
wb_rst_i : in std_logic; -- reset signal
wb_sel_i : in std_logic; -- select input
wb_stb_i : in std_logic; -- strobe input
wb_we_i : in std_logic; -- write enable
wb_cyc_i : in std_logic; -- cycle input
wb_bte_i : in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i : in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o : out std_logic; -- acknowledge
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd : out std_logic; -- Version register read
config_rd : out std_logic; -- Config register read
config_wr : out std_logic; -- Config register write
intmask_rd : out std_logic; -- Interrupt mask register read
intmask_wr : out std_logic; -- Interrupt mask register write
intstat_rd : out std_logic; -- Interrupt status register read
intstat_wr : out std_logic; -- Interrupt status register read
mem_rd : out std_logic; -- Sample memory write
mem_addr : out std_logic_vector(ADDR_WIDTH - 2 downto 0)); -- memory addr.
end component;
 
component i2s_codec
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 component;
 
end rx_i2s_pack;
/trunk/rtl/vhdl/tx_i2s_wbd.vhd
44,6 → 44,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.3 2005/01/17 17:26:49 gedra
-- Bugfix of register read/write strobes
--
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
57,128 → 60,128
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity tx_i2s_wbd is
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer);
port (
wb_clk_i: in std_logic; -- wishbone clock
wb_rst_i: in std_logic; -- reset signal
wb_sel_i: in std_logic; -- select input
wb_stb_i: in std_logic; -- strobe input
wb_we_i: in std_logic; -- write enable
wb_cyc_i: in std_logic; -- cycle input
wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o: out std_logic; -- acknowledge
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd: out std_logic; -- Version register read
config_rd: out std_logic; -- Config register read
config_wr: out std_logic; -- Config register write
intmask_rd: out std_logic; -- Interrupt mask register read
intmask_wr: out std_logic; -- Interrupt mask register write
intstat_rd: out std_logic; -- Interrupt status register read
intstat_wr: out std_logic; -- Interrupt status register read
mem_wr: out std_logic); -- Sample memory write
entity tx_i2s_wbd is
generic (DATA_WIDTH : integer;
ADDR_WIDTH : integer);
port (
wb_clk_i : in std_logic; -- wishbone clock
wb_rst_i : in std_logic; -- reset signal
wb_sel_i : in std_logic; -- select input
wb_stb_i : in std_logic; -- strobe input
wb_we_i : in std_logic; -- write enable
wb_cyc_i : in std_logic; -- cycle input
wb_bte_i : in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i : in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o : out std_logic; -- acknowledge
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd : out std_logic; -- Version register read
config_rd : out std_logic; -- Config register read
config_wr : out std_logic; -- Config register write
intmask_rd : out std_logic; -- Interrupt mask register read
intmask_wr : out std_logic; -- Interrupt mask register write
intstat_rd : out std_logic; -- Interrupt status register read
intstat_wr : out std_logic; -- Interrupt status register read
mem_wr : out std_logic); -- Sample memory write
end tx_i2s_wbd;
 
architecture rtl of tx_i2s_wbd is
constant REG_TXVERSION : std_logic_vector(3 downto 0) := "0000";
constant REG_TXCONFIG : std_logic_vector(3 downto 0) := "0001";
constant REG_TXINTMASK : std_logic_vector(3 downto 0) := "0010";
constant REG_TXINTSTAT : std_logic_vector(3 downto 0) := "0011";
signal iack, iwr, ird : std_logic;
signal acnt: integer range 0 to 2**(ADDR_WIDTH - 1) - 1;
signal rdout : std_logic_vector(DATA_WIDTH - 1 downto 0);
begin
constant REG_TXVERSION : std_logic_vector(3 downto 0) := "0000";
constant REG_TXCONFIG : std_logic_vector(3 downto 0) := "0001";
constant REG_TXINTMASK : std_logic_vector(3 downto 0) := "0010";
constant REG_TXINTSTAT : std_logic_vector(3 downto 0) := "0011";
signal iack, iwr, ird : std_logic;
signal acnt : integer range 0 to 2**(ADDR_WIDTH - 1) - 1;
signal rdout : std_logic_vector(DATA_WIDTH - 1 downto 0);
begin
 
wb_ack_o <= iack;
wb_ack_o <= iack;
 
-- acknowledge generation
ACK: process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iack <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iack <= '1';
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
when "111" => -- end of burst
iack <= not iack;
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
else
iack <= '0';
end if;
end if;
end process ACK;
ACK : process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iack <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iack <= '1';
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
when "111" => -- end of burst
iack <= not iack;
when others => -- all other treated assert classic cycle
iack <= not iack;
end case;
else
iack <= '0';
end if;
end if;
end process ACK;
 
-- write generation
WR: process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iwr <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iwr <= '1';
when others => -- all other treated as classic cycle
iwr <= not iwr;
end case;
when "111" => -- end of burst
iwr <= not iwr;
when others => -- all other treated as classic cycle
iwr <= not iwr;
end case;
else
iwr <= '0';
end if;
end if;
end process WR;
WR : process (wb_clk_i, wb_rst_i)
begin
if wb_rst_i = '1' then
iwr <= '0';
elsif rising_edge(wb_clk_i) then
if wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '1' then
case wb_cti_i is
when "010" => -- incrementing burst
case wb_bte_i is -- burst extension
when "00" => -- linear burst
iwr <= '1';
when others => -- all other treated as classic cycle
iwr <= not iwr;
end case;
when "111" => -- end of burst
iwr <= not iwr;
when others => -- all other treated as classic cycle
iwr <= not iwr;
end case;
else
iwr <= '0';
end if;
end if;
end process WR;
 
-- read generation
ird <= '1' when wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '0' else '0';
ird <= '1' when wb_cyc_i = '1' and wb_sel_i = '1' and wb_stb_i = '1' and
wb_we_i = '0' else '0';
 
wb_dat_o <= data_out when wb_adr_i(ADDR_WIDTH - 1) = '1' else rdout;
wb_dat_o <= data_out when wb_adr_i(ADDR_WIDTH - 1) = '1' else rdout;
 
DREG: process (wb_clk_i) -- clock data from registers
begin
if rising_edge(wb_clk_i) then
rdout <= data_out;
end if;
end process DREG;
DREG : process (wb_clk_i) -- clock data from registers
begin
if rising_edge(wb_clk_i) then
rdout <= data_out;
end if;
end process DREG;
 
-- read and write strobe generation
version_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXVERSION and ird = '1'
 
version_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXVERSION and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
config_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXCONFIG and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
config_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXCONFIG and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
config_wr <= '1' when wb_adr_i(3 downto 0) = REG_TXCONFIG and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intmask_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXINTMASK and ird = '1'
config_wr <= '1' when wb_adr_i(3 downto 0) = REG_TXCONFIG and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intmask_wr <= '1' when wb_adr_i(3 downto 0) = REG_TXINTMASK and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXINTSTAT and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_wr <= '1' when wb_adr_i(3 downto 0) = REG_TXINTSTAT and iwr = '1'
else '0';
mem_wr <= '1' when wb_adr_i(ADDR_WIDTH - 1) = '1' and iwr = '1' else '0';
intmask_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXINTMASK and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intmask_wr <= '1' when wb_adr_i(3 downto 0) = REG_TXINTMASK and iwr = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_rd <= '1' when wb_adr_i(3 downto 0) = REG_TXINTSTAT and ird = '1'
and wb_adr_i(ADDR_WIDTH - 1) = '0' else '0';
intstat_wr <= '1' when wb_adr_i(3 downto 0) = REG_TXINTSTAT and iwr = '1'
else '0';
mem_wr <= '1' when wb_adr_i(ADDR_WIDTH - 1) = '1' and iwr = '1' else '0';
end rtl;
/trunk/rtl/vhdl/rx_i2s_topm.vhd
44,6 → 44,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
-- Revision 1.1 2004/08/04 14:29:34 gedra
-- Receiver top level, master mode.
--
54,220 → 57,220
use ieee.std_logic_1164.all;
use work.rx_i2s_pack.all;
 
entity rx_i2s_topm is
generic (DATA_WIDTH: integer range 16 to 32;
ADDR_WIDTH: integer range 5 to 32);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic;
wb_sel_i: in std_logic;
wb_stb_i: in std_logic;
wb_we_i: in std_logic;
wb_cyc_i: in std_logic;
wb_bte_i: in std_logic_vector(1 downto 0);
wb_cti_i: in std_logic_vector(2 downto 0);
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0);
i2s_sd_i: in std_logic; -- I2S data input
wb_ack_o: out std_logic;
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0);
rx_int_o: out std_logic; -- Interrupt line
i2s_sck_o: out std_logic; -- I2S clock out
i2s_ws_o: out std_logic); -- I2S word select out
entity rx_i2s_topm is
generic (DATA_WIDTH : integer range 16 to 32;
ADDR_WIDTH : integer range 5 to 32);
port (
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_cyc_i : in std_logic;
wb_bte_i : in std_logic_vector(1 downto 0);
wb_cti_i : in std_logic_vector(2 downto 0);
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i : in std_logic_vector(DATA_WIDTH -1 downto 0);
i2s_sd_i : in std_logic; -- I2S data input
wb_ack_o : out std_logic;
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0);
rx_int_o : out std_logic; -- Interrupt line
i2s_sck_o : out std_logic; -- I2S clock out
i2s_ws_o : out std_logic); -- I2S word select out
end rx_i2s_topm;
 
architecture rtl of rx_i2s_topm is
 
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr: std_logic;
signal intstat_events: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd: std_logic;
signal sbuf_rd_adr, sbuf_wr_adr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sbuf_dout, sbuf_din, zeros: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_rswap, conf_rinten, conf_rxen : std_logic;
signal zero: std_logic;
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr : std_logic;
signal intstat_events : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd : std_logic;
signal sbuf_rd_adr, sbuf_wr_adr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sbuf_dout, sbuf_din, zeros : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_rswap, conf_rinten, conf_rxen : std_logic;
signal zero : std_logic;
begin
 
-- Data bus or'ing
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else sbuf_dout;
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else sbuf_dout;
 
-- Wishbone bus cycle decoder
WB: rx_i2s_wbd
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_rd => mem_rd,
mem_addr => sbuf_rd_adr);
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1)
port map (
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32: if DATA_WIDTH = 32 generate
CONF: gen_control_reg
WB : rx_i2s_wbd
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16: if DATA_WIDTH = 16 generate
CONF: gen_control_reg
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_rd => mem_rd,
mem_addr => sbuf_rd_adr);
 
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_rswap <= config_bits(2);
conf_rinten <= config_bits(1);
conf_rxen <= config_bits(0);
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32 : if DATA_WIDTH = 32 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16 : if DATA_WIDTH = 16 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_rswap <= config_bits(2);
conf_rinten <= config_bits(1);
conf_rxen <= config_bits(0);
 
-- TxIntMask - interrupt mask register
IM32: if DATA_WIDTH = 32 generate
IMASK: gen_control_reg
IM32 : if DATA_WIDTH = 32 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16 : if DATA_WIDTH = 16 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
 
-- TxIntStat - interrupt status register
ISTAT : gen_event_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16: if DATA_WIDTH = 16 generate
IMASK: gen_control_reg
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_rinten,
evt_irq => rx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
 
-- Sample buffer memory
MEM : dpram
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
-- TxIntStat - interrupt status register
ISTAT: gen_event_reg
generic map (
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_rinten,
evt_irq => rx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
-- Sample buffer memory
MEM: dpram
generic map (
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
din => sbuf_din,
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => sbuf_wr_adr,
rd_addr => sbuf_rd_adr,
dout => sbuf_dout);
clk => wb_clk_i,
rst => wb_rst_i,
din => sbuf_din,
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => sbuf_wr_adr,
rd_addr => sbuf_rd_adr,
dout => sbuf_dout);
 
-- Receive decoder
zero <= '0';
zeros <= (others => '0');
DEC: i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1,
IS_RECEIVER => 1)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_rswap,
conf_en => conf_rxen,
i2s_sd_i => i2s_sd_i,
i2s_sck_i => zero,
i2s_ws_i => zero,
sample_dat_i => zeros,
sample_dat_o => sbuf_din,
mem_rdwr => mem_wr,
sample_addr => sbuf_wr_adr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => open,
i2s_sck_o => i2s_sck_o,
i2s_ws_o => i2s_ws_o);
zero <= '0';
zeros <= (others => '0');
 
DEC : i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1,
IS_RECEIVER => 1)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_rswap,
conf_en => conf_rxen,
i2s_sd_i => i2s_sd_i,
i2s_sck_i => zero,
i2s_ws_i => zero,
sample_dat_i => zeros,
sample_dat_o => sbuf_din,
mem_rdwr => mem_wr,
sample_addr => sbuf_wr_adr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => open,
i2s_sck_o => i2s_sck_o,
i2s_ws_o => i2s_ws_o);
 
end rtl;
 
/trunk/rtl/vhdl/tx_i2s_pack.vhd
43,120 → 43,123
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
-- Revision 1.1 2004/08/04 14:29:10 gedra
-- Transmitter component declarations.
--
--
--
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
 
package tx_i2s_pack is
 
-- components used in the transmitter
component gen_control_reg
generic (DATA_WIDTH: integer;
-- note that this vector is (0 to xx), reverse order
ACTIVE_BIT_MASK: std_logic_vector);
port (
clk: in std_logic; -- clock
rst: in std_logic; -- reset
ctrl_wr: in std_logic; -- control register write
ctrl_rd: in std_logic; -- control register read
ctrl_din: in std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_bits: out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
component gen_control_reg
generic (DATA_WIDTH : integer;
-- note that this vector is (0 to xx), reverse order
ACTIVE_BIT_MASK : std_logic_vector);
port (
clk : in std_logic; -- clock
rst : in std_logic; -- reset
ctrl_wr : in std_logic; -- control register write
ctrl_rd : in std_logic; -- control register read
ctrl_din : in std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_dout : out std_logic_vector(DATA_WIDTH - 1 downto 0);
ctrl_bits : out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
 
component gen_event_reg
generic (DATA_WIDTH: integer);
port (
clk: in std_logic; -- clock
rst: in std_logic; -- reset
evt_wr: in std_logic; -- event register write
evt_rd: in std_logic; -- event register read
evt_din: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data
event: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- event vector
evt_mask: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- irq mask
evt_en: in std_logic; -- irq enable
evt_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data
evt_irq: out std_logic); -- interrupt request
end component;
component gen_event_reg
generic (DATA_WIDTH : integer);
port (
clk : in std_logic; -- clock
rst : in std_logic; -- reset
evt_wr : in std_logic; -- event register write
evt_rd : in std_logic; -- event register read
evt_din : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- write data
event : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- event vector
evt_mask : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- irq mask
evt_en : in std_logic; -- irq enable
evt_dout : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- read data
evt_irq : out std_logic); -- interrupt request
end component;
 
component dpram
generic (DATA_WIDTH: positive;
RAM_WIDTH: positive);
port (
clk: in std_logic;
rst: in std_logic; -- reset is optional, not used here
din: in std_logic_vector(DATA_WIDTH - 1 downto 0);
wr_en: in std_logic;
rd_en: in std_logic;
wr_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0);
rd_addr: in std_logic_vector(RAM_WIDTH - 1 downto 0);
dout: out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
component dpram
generic (DATA_WIDTH : positive;
RAM_WIDTH : positive);
port (
clk : in std_logic;
rst : in std_logic; -- reset is optional, not used here
din : in std_logic_vector(DATA_WIDTH - 1 downto 0);
wr_en : in std_logic;
rd_en : in std_logic;
wr_addr : in std_logic_vector(RAM_WIDTH - 1 downto 0);
rd_addr : in std_logic_vector(RAM_WIDTH - 1 downto 0);
dout : out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
 
component i2s_version
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer;
IS_MASTER: integer);
port (
ver_rd: in std_logic; -- version register read
ver_dout: out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
component i2s_version
generic (DATA_WIDTH : integer;
ADDR_WIDTH : integer;
IS_MASTER : integer);
port (
ver_rd : in std_logic; -- version register read
ver_dout : out std_logic_vector(DATA_WIDTH - 1 downto 0));
end component;
 
component tx_i2s_wbd
generic (DATA_WIDTH: integer;
ADDR_WIDTH: integer);
port (
wb_clk_i: in std_logic; -- wishbone clock
wb_rst_i: in std_logic; -- reset signal
wb_sel_i: in std_logic; -- select input
wb_stb_i: in std_logic; -- strobe input
wb_we_i: in std_logic; -- write enable
wb_cyc_i: in std_logic; -- cycle input
wb_bte_i: in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i: in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out: in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o: out std_logic; -- acknowledge
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd: out std_logic; -- Version register read
config_rd: out std_logic; -- Config register read
config_wr: out std_logic; -- Config register write
intmask_rd: out std_logic; -- Interrupt mask register read
intmask_wr: out std_logic; -- Interrupt mask register write
intstat_rd: out std_logic; -- Interrupt status register read
intstat_wr: out std_logic; -- Interrupt status register read
mem_wr: out std_logic); -- Sample memory write
end component;
component tx_i2s_wbd
generic (DATA_WIDTH : integer;
ADDR_WIDTH : integer);
port (
wb_clk_i : in std_logic; -- wishbone clock
wb_rst_i : in std_logic; -- reset signal
wb_sel_i : in std_logic; -- select input
wb_stb_i : in std_logic; -- strobe input
wb_we_i : in std_logic; -- write enable
wb_cyc_i : in std_logic; -- cycle input
wb_bte_i : in std_logic_vector(1 downto 0); -- burts type extension
wb_cti_i : in std_logic_vector(2 downto 0); -- cycle type identifier
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0); -- address
data_out : in std_logic_vector(DATA_WIDTH - 1 downto 0); -- internal bus
wb_ack_o : out std_logic; -- acknowledge
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0); -- data out
version_rd : out std_logic; -- Version register read
config_rd : out std_logic; -- Config register read
config_wr : out std_logic; -- Config register write
intmask_rd : out std_logic; -- Interrupt mask register read
intmask_wr : out std_logic; -- Interrupt mask register write
intstat_rd : out std_logic; -- Interrupt status register read
intstat_wr : out std_logic; -- Interrupt status register read
mem_wr : out std_logic); -- Sample memory write
end component;
 
component i2s_codec
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 component;
component i2s_codec
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 component;
 
end tx_i2s_pack;
/trunk/rtl/vhdl/tx_i2s_topm.vhd
44,6 → 44,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
-- Revision 1.1 2004/08/04 14:30:14 gedra
-- Transmitter top level, master mode.
--
54,221 → 57,221
use ieee.std_logic_1164.all;
use work.tx_i2s_pack.all;
 
entity tx_i2s_topm is
generic (DATA_WIDTH: integer range 16 to 32;
ADDR_WIDTH: integer range 5 to 32);
port (
-- Wishbone interface
wb_clk_i: in std_logic;
wb_rst_i: in std_logic;
wb_sel_i: in std_logic;
wb_stb_i: in std_logic;
wb_we_i: in std_logic;
wb_cyc_i: in std_logic;
wb_bte_i: in std_logic_vector(1 downto 0);
wb_cti_i: in std_logic_vector(2 downto 0);
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0);
wb_ack_o: out std_logic;
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0);
-- Interrupt line
tx_int_o: out std_logic;
-- I2S signals
i2s_sd_o: out std_logic;
i2s_sck_o: out std_logic;
i2s_ws_o: out std_logic);
entity tx_i2s_topm is
generic (DATA_WIDTH : integer range 16 to 32;
ADDR_WIDTH : integer range 5 to 32);
port (
-- Wishbone interface
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_cyc_i : in std_logic;
wb_bte_i : in std_logic_vector(1 downto 0);
wb_cti_i : in std_logic_vector(2 downto 0);
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i : in std_logic_vector(DATA_WIDTH -1 downto 0);
wb_ack_o : out std_logic;
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0);
-- Interrupt line
tx_int_o : out std_logic;
-- I2S signals
i2s_sd_o : out std_logic;
i2s_sck_o : out std_logic;
i2s_ws_o : out std_logic);
end tx_i2s_topm;
 
architecture rtl of tx_i2s_topm is
 
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr: std_logic;
signal intstat_events: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd: std_logic;
signal sample_addr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sample_data: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_tswap, conf_tinten, conf_txen : std_logic;
signal zero : std_logic;
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr : std_logic;
signal intstat_events : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd : std_logic;
signal sample_addr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sample_data : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_tswap, conf_tinten, conf_txen : std_logic;
signal zero : std_logic;
begin
 
-- Data bus or'ing
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else (others => '0');
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else (others => '0');
 
-- Wishbone bus cycle decoder
WB: tx_i2s_wbd
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_wr => mem_wr);
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1)
port map (
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32: if DATA_WIDTH = 32 generate
CONF: gen_control_reg
WB : tx_i2s_wbd
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16: if DATA_WIDTH = 16 generate
CONF: gen_control_reg
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_wr => mem_wr);
 
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_tswap <= config_bits(2);
conf_tinten <= config_bits(1);
conf_txen <= config_bits(0);
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32 : if DATA_WIDTH = 32 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16 : if DATA_WIDTH = 16 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_tswap <= config_bits(2);
conf_tinten <= config_bits(1);
conf_txen <= config_bits(0);
 
-- TxIntMask - interrupt mask register
IM32: if DATA_WIDTH = 32 generate
IMASK: gen_control_reg
IM32 : if DATA_WIDTH = 32 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16 : if DATA_WIDTH = 16 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
 
-- TxIntStat - interrupt status register
ISTAT : gen_event_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16: if DATA_WIDTH = 16 generate
IMASK: gen_control_reg
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_tinten,
evt_irq => tx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
 
-- Sample buffer memory
MEM : dpram
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
-- TxIntStat - interrupt status register
ISTAT: gen_event_reg
generic map (
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_tinten,
evt_irq => tx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
-- Sample buffer memory
MEM: dpram
generic map (
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
din => wb_dat_i(DATA_WIDTH - 1 downto 0),
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => wb_adr_i(ADDR_WIDTH - 2 downto 0),
rd_addr => sample_addr,
dout => sample_data);
clk => wb_clk_i,
rst => wb_rst_i,
din => wb_dat_i(DATA_WIDTH - 1 downto 0),
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => wb_adr_i(ADDR_WIDTH - 2 downto 0),
rd_addr => sample_addr,
dout => sample_data);
 
-- Transmit encoder
zero <= '0';
ENC: i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1,
IS_RECEIVER => 0)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_tswap,
conf_en => conf_txen,
i2s_sd_i => zero,
i2s_sck_i => zero,
i2s_ws_i => zero,
sample_dat_i => sample_data,
sample_dat_o => open,
mem_rdwr => mem_rd,
sample_addr => sample_addr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => i2s_sd_o,
i2s_sck_o => i2s_sck_o,
i2s_ws_o => i2s_ws_o);
zero <= '0';
 
ENC : i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 1,
IS_RECEIVER => 0)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_tswap,
conf_en => conf_txen,
i2s_sd_i => zero,
i2s_sck_i => zero,
i2s_ws_i => zero,
sample_dat_i => sample_data,
sample_dat_o => open,
mem_rdwr => mem_rd,
sample_addr => sample_addr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => i2s_sd_o,
i2s_sck_o => i2s_sck_o,
i2s_ws_o => i2s_ws_o);
 
end rtl;
 
/trunk/rtl/vhdl/i2s_codec.vhd
44,6 → 44,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- 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.
--
57,399 → 60,399
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
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
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;
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;
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;
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;
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
i2s_ws <= not i2s_ws;
ws_cnt <= 0;
if i2s_ws = '1' then
ws_neg_edge <= '1';
else
ws_pos_edge <= '1';
end if;
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;
else
ws_pos_edge <= '0';
ws_neg_edge <= '0';
end if;
end if;
end if;
end process WSG;
end generate WSM;
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';
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;
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';
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;
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;
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
imem_rdwr <= '1';
data_in(bits_to_trx - bit_cnt) <= i2s_sd_i;
sd_ctrl <= RX_WRITE;
bits_to_trx <= 15;
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;
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
imem_rdwr <= '1';
sd_ctrl <= RX_WRITE;
if ws_pos_edge = '1' or ws_neg_edge = '1' then
new_word <= '1';
end if;
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);
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
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);
evt_lsbf <= '0';
end if;
if adr_cnt = 2**(ADDR_WIDTH - 1) - 1 then
evt_hsbf <= '1';
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;
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 if;
end process SDRX;
end process SDRX;
end rtl;
/trunk/rtl/vhdl/rx_i2s_tops.vhd
44,6 → 44,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
-- Revision 1.1 2004/08/04 14:29:50 gedra
-- Receiver top level, slave mode.
--
54,220 → 57,220
use ieee.std_logic_1164.all;
use work.rx_i2s_pack.all;
 
entity rx_i2s_tops is
generic (DATA_WIDTH: integer range 16 to 32;
ADDR_WIDTH: integer range 5 to 32);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic;
wb_sel_i: in std_logic;
wb_stb_i: in std_logic;
wb_we_i: in std_logic;
wb_cyc_i: in std_logic;
wb_bte_i: in std_logic_vector(1 downto 0);
wb_cti_i: in std_logic_vector(2 downto 0);
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0);
i2s_sd_i: in std_logic; -- I2S data input
i2s_sck_i: in std_logic; -- I2S clock input
i2s_ws_i: in std_logic; -- I2S word select input
wb_ack_o: out std_logic;
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0);
rx_int_o: out std_logic); -- Interrupt line
entity rx_i2s_tops is
generic (DATA_WIDTH : integer range 16 to 32;
ADDR_WIDTH : integer range 5 to 32);
port (
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_cyc_i : in std_logic;
wb_bte_i : in std_logic_vector(1 downto 0);
wb_cti_i : in std_logic_vector(2 downto 0);
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i : in std_logic_vector(DATA_WIDTH -1 downto 0);
i2s_sd_i : in std_logic; -- I2S data input
i2s_sck_i : in std_logic; -- I2S clock input
i2s_ws_i : in std_logic; -- I2S word select input
wb_ack_o : out std_logic;
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0);
rx_int_o : out std_logic); -- Interrupt line
end rx_i2s_tops;
 
architecture rtl of rx_i2s_tops is
 
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr: std_logic;
signal intstat_events: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd: std_logic;
signal sbuf_rd_adr, sbuf_wr_adr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sbuf_dout, sbuf_din, zeros: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_rswap, conf_rinten, conf_rxen : std_logic;
signal zero: std_logic;
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr : std_logic;
signal intstat_events : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd : std_logic;
signal sbuf_rd_adr, sbuf_wr_adr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sbuf_dout, sbuf_din, zeros : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_rswap, conf_rinten, conf_rxen : std_logic;
signal zero : std_logic;
begin
 
-- Data bus or'ing
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else sbuf_dout;
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else sbuf_dout;
 
-- Wishbone bus cycle decoder
WB: rx_i2s_wbd
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_rd => mem_rd,
mem_addr => sbuf_rd_adr);
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0)
port map (
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32: if DATA_WIDTH = 32 generate
CONF: gen_control_reg
WB : rx_i2s_wbd
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16: if DATA_WIDTH = 16 generate
CONF: gen_control_reg
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_rd => mem_rd,
mem_addr => sbuf_rd_adr);
 
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_rswap <= config_bits(2);
conf_rinten <= config_bits(1);
conf_rxen <= config_bits(0);
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32 : if DATA_WIDTH = 32 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16 : if DATA_WIDTH = 16 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_rswap <= config_bits(2);
conf_rinten <= config_bits(1);
conf_rxen <= config_bits(0);
 
-- TxIntMask - interrupt mask register
IM32: if DATA_WIDTH = 32 generate
IMASK: gen_control_reg
IM32 : if DATA_WIDTH = 32 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16 : if DATA_WIDTH = 16 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
 
-- TxIntStat - interrupt status register
ISTAT : gen_event_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16: if DATA_WIDTH = 16 generate
IMASK: gen_control_reg
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_rinten,
evt_irq => rx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
 
-- Sample buffer memory
MEM : dpram
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
-- TxIntStat - interrupt status register
ISTAT: gen_event_reg
generic map (
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_rinten,
evt_irq => rx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
-- Sample buffer memory
MEM: dpram
generic map (
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
din => sbuf_din,
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => sbuf_wr_adr,
rd_addr => sbuf_rd_adr,
dout => sbuf_dout);
clk => wb_clk_i,
rst => wb_rst_i,
din => sbuf_din,
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => sbuf_wr_adr,
rd_addr => sbuf_rd_adr,
dout => sbuf_dout);
 
-- Receive decoder
zero <= '0';
zeros <= (others => '0');
DEC: i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0,
IS_RECEIVER => 1)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_rswap,
conf_en => conf_rxen,
i2s_sd_i => i2s_sd_i,
i2s_sck_i => i2s_sck_i,
i2s_ws_i => i2s_ws_i,
sample_dat_i => zeros,
sample_dat_o => sbuf_din,
mem_rdwr => mem_wr,
sample_addr => sbuf_wr_adr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => open,
i2s_sck_o => open,
i2s_ws_o => open);
zero <= '0';
zeros <= (others => '0');
 
DEC : i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0,
IS_RECEIVER => 1)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_rswap,
conf_en => conf_rxen,
i2s_sd_i => i2s_sd_i,
i2s_sck_i => i2s_sck_i,
i2s_ws_i => i2s_ws_i,
sample_dat_i => zeros,
sample_dat_o => sbuf_din,
mem_rdwr => mem_wr,
sample_addr => sbuf_wr_adr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => open,
i2s_sck_o => open,
i2s_ws_o => open);
 
end rtl;
 
/trunk/rtl/vhdl/tx_i2s_tops.vhd
44,6 → 44,9
-- CVS Revision History
--
-- $Log: not supported by cvs2svn $
-- Revision 1.2 2004/08/06 18:55:43 gedra
-- De-linting.
--
-- Revision 1.1 2004/08/04 14:30:28 gedra
-- Transmitter top level, slave mode.
--
54,218 → 57,218
use ieee.std_logic_1164.all;
use work.tx_i2s_pack.all;
 
entity tx_i2s_tops is
generic (DATA_WIDTH: integer range 16 to 32;
ADDR_WIDTH: integer range 5 to 32);
port (
wb_clk_i: in std_logic;
wb_rst_i: in std_logic;
wb_sel_i: in std_logic;
wb_stb_i: in std_logic;
wb_we_i: in std_logic;
wb_cyc_i: in std_logic;
wb_bte_i: in std_logic_vector(1 downto 0);
wb_cti_i: in std_logic_vector(2 downto 0);
wb_adr_i: in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i: in std_logic_vector(DATA_WIDTH -1 downto 0);
i2s_sck_i: in std_logic;
i2s_ws_i: in std_logic;
wb_ack_o: out std_logic;
wb_dat_o: out std_logic_vector(DATA_WIDTH - 1 downto 0);
tx_int_o: out std_logic;
i2s_sd_o: out std_logic);
entity tx_i2s_tops is
generic (DATA_WIDTH : integer range 16 to 32;
ADDR_WIDTH : integer range 5 to 32);
port (
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_sel_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_cyc_i : in std_logic;
wb_bte_i : in std_logic_vector(1 downto 0);
wb_cti_i : in std_logic_vector(2 downto 0);
wb_adr_i : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
wb_dat_i : in std_logic_vector(DATA_WIDTH -1 downto 0);
i2s_sck_i : in std_logic;
i2s_ws_i : in std_logic;
wb_ack_o : out std_logic;
wb_dat_o : out std_logic_vector(DATA_WIDTH - 1 downto 0);
tx_int_o : out std_logic;
i2s_sd_o : out std_logic);
end tx_i2s_tops;
 
architecture rtl of tx_i2s_tops is
 
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr: std_logic;
signal intstat_events: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd: std_logic;
signal sample_addr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sample_data: std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_tswap, conf_tinten, conf_txen : std_logic;
signal zero : std_logic;
signal data_out, version_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal version_rd : std_logic;
signal config_rd, config_wr, status_rd : std_logic;
signal config_dout, status_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal config_bits : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_bits, intmask_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intmask_rd, intmask_wr : std_logic;
signal intstat_events : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_dout : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal intstat_rd, intstat_wr : std_logic;
signal evt_hsbf, evt_lsbf : std_logic;
signal mem_wr, mem_rd : std_logic;
signal sample_addr : std_logic_vector(ADDR_WIDTH - 2 downto 0);
signal sample_data : std_logic_vector(DATA_WIDTH - 1 downto 0);
signal conf_ratio : std_logic_vector(7 downto 0);
signal conf_res : std_logic_vector(5 downto 0);
signal conf_tswap, conf_tinten, conf_txen : std_logic;
signal zero : std_logic;
begin
 
-- Data bus or'ing
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else (others => '0');
data_out <= version_dout or config_dout or intmask_dout or intstat_dout
when wb_adr_i(ADDR_WIDTH - 1) = '0' else (others => '0');
 
-- Wishbone bus cycle decoder
WB: tx_i2s_wbd
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_wr => mem_wr);
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0)
port map (
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32: if DATA_WIDTH = 32 generate
CONF: gen_control_reg
WB : tx_i2s_wbd
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16: if DATA_WIDTH = 16 generate
CONF: gen_control_reg
wb_clk_i => wb_clk_i,
wb_rst_i => wb_rst_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_cyc_i => wb_cyc_i,
wb_bte_i => wb_bte_i,
wb_cti_i => wb_cti_i,
wb_adr_i => wb_adr_i,
data_out => data_out,
wb_ack_o => wb_ack_o,
wb_dat_o => wb_dat_o,
version_rd => version_rd,
config_rd => config_rd,
config_wr => config_wr,
intmask_rd => intmask_rd,
intmask_wr => intmask_wr,
intstat_rd => intstat_rd,
intstat_wr => intstat_wr,
mem_wr => mem_wr);
 
-- TxVersion - Version register
VER : i2s_version
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_tswap <= config_bits(2);
conf_tinten <= config_bits(1);
conf_txen <= config_bits(0);
ver_rd => version_rd,
ver_dout => version_dout);
 
-- TxConfig - Configuration register
CG32 : if DATA_WIDTH = 32 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11100000111111111111110000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= config_bits(21 downto 16);
end generate CG32;
CG16 : if DATA_WIDTH = 16 generate
CONF : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1110000011111111")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => config_wr,
ctrl_rd => config_rd,
ctrl_din => wb_dat_i,
ctrl_dout => config_dout,
ctrl_bits => config_bits);
conf_res(5 downto 0) <= "010000"; -- 16bit only
end generate CG16;
conf_ratio(7 downto 0) <= config_bits(15 downto 8);
conf_tswap <= config_bits(2);
conf_tinten <= config_bits(1);
conf_txen <= config_bits(0);
 
-- TxIntMask - interrupt mask register
IM32: if DATA_WIDTH = 32 generate
IMASK: gen_control_reg
IM32 : if DATA_WIDTH = 32 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16 : if DATA_WIDTH = 16 generate
IMASK : gen_control_reg
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
 
-- TxIntStat - interrupt status register
ISTAT : gen_event_reg
generic map (
DATA_WIDTH => 32,
ACTIVE_BIT_MASK => "11000000000000000000000000000000")
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM32;
IM16: if DATA_WIDTH = 16 generate
IMASK: gen_control_reg
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_tinten,
evt_irq => tx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
 
-- Sample buffer memory
MEM : dpram
generic map (
DATA_WIDTH => 16,
ACTIVE_BIT_MASK => "1100000000000000")
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
ctrl_wr => intmask_wr,
ctrl_rd => intmask_rd,
ctrl_din => wb_dat_i,
ctrl_dout => intmask_dout,
ctrl_bits => intmask_bits);
end generate IM16;
-- TxIntStat - interrupt status register
ISTAT: gen_event_reg
generic map (
DATA_WIDTH => DATA_WIDTH)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
evt_wr => intstat_wr,
evt_rd => intstat_rd,
evt_din => wb_dat_i,
evt_dout => intstat_dout,
event => intstat_events,
evt_mask => intmask_bits,
evt_en => conf_tinten,
evt_irq => tx_int_o);
intstat_events(0) <= evt_lsbf; -- lower sample buffer empty
intstat_events(1) <= evt_hsbf; -- higher sampel buffer empty
intstat_events(DATA_WIDTH - 1 downto 2) <= (others => '0');
-- Sample buffer memory
MEM: dpram
generic map (
DATA_WIDTH => DATA_WIDTH,
RAM_WIDTH => ADDR_WIDTH - 1)
port map (
clk => wb_clk_i,
rst => wb_rst_i,
din => wb_dat_i(DATA_WIDTH - 1 downto 0),
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => wb_adr_i(ADDR_WIDTH - 2 downto 0),
rd_addr => sample_addr,
dout => sample_data);
clk => wb_clk_i,
rst => wb_rst_i,
din => wb_dat_i(DATA_WIDTH - 1 downto 0),
wr_en => mem_wr,
rd_en => mem_rd,
wr_addr => wb_adr_i(ADDR_WIDTH - 2 downto 0),
rd_addr => sample_addr,
dout => sample_data);
 
-- Transmit encoder
zero <= '0';
ENC: i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0,
IS_RECEIVER => 0)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_tswap,
conf_en => conf_txen,
i2s_sd_i => zero,
i2s_sck_i => i2s_sck_i,
i2s_ws_i => i2s_ws_i,
sample_dat_i => sample_data,
sample_dat_o => open,
mem_rdwr => mem_rd,
sample_addr => sample_addr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => i2s_sd_o,
i2s_sck_o => open,
i2s_ws_o => open);
zero <= '0';
 
ENC : i2s_codec
generic map (DATA_WIDTH => DATA_WIDTH,
ADDR_WIDTH => ADDR_WIDTH,
IS_MASTER => 0,
IS_RECEIVER => 0)
port map (
wb_clk_i => wb_clk_i,
conf_res => conf_res,
conf_ratio => conf_ratio,
conf_swap => conf_tswap,
conf_en => conf_txen,
i2s_sd_i => zero,
i2s_sck_i => i2s_sck_i,
i2s_ws_i => i2s_ws_i,
sample_dat_i => sample_data,
sample_dat_o => open,
mem_rdwr => mem_rd,
sample_addr => sample_addr,
evt_hsbf => evt_hsbf,
evt_lsbf => evt_lsbf,
i2s_sd_o => i2s_sd_o,
i2s_sck_o => open,
i2s_ws_o => open);
 
end rtl;
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.