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; |
|