Radical Computer Technologies
Interfaces / entity

radif_i2s_axis

Documentation version: 0.2.0 / Subpackage: radif_i2s / Source package: radif

Bidirectional I2S to AXI-Stream bridge. Converts stereo I2S samples to AXI-Stream frames and AXI-Stream frames back to I2S while exposing clocking and enable controls through a RADIF register interface.

Use Cases

Block Diagram

radif_i2s_axis radhdl entity S_AXIS clk rstn reg_wr_addr reg_rd_addr reg_wr_en reg_rd_en reg_data_in i2s_mclk_i i2s_bclk_i i2s_lrck_i i2s_sdata_i M_AXIS reg_data_out reg_wr_rdy reg_rd_rdy reg_wr_valid reg_rd_valid reg_error i2s_mclk_o i2s_mclk_oe i2s_bclk_o i2s_bclk_oe i2s_lrck_o i2s_lrck_oe i2s_sdata_o i2s_sdata_oe
VHDL Include And Instantiation Template

File Header

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

library radhdl;
-- Direct entity instantiation below does not require importing the entity name.
use radhdl.interfaces.all;
-- Narrower alternative: use radhdl.interfaces_i2s.all;

Component Declaration

component radif_i2s_axis is
  generic (
    SAMPLE_WIDTH : positive := 24;
    AXIS_DATA_WIDTH : positive := 64;
    REG_DATA_WIDTH : positive := 32;
    REG_ADDR_WIDTH : positive := 16;
    DEFAULT_MCLK_DIV : natural := 1;
    DEFAULT_BCLK_DIV : natural := 7;
    DEFAULT_LRCK_BITS : positive := 32;
    USE_EXTERNAL_MCLK : boolean := false;
    NO_MCLK : boolean := false;
    USE_EXTERNAL_BCLK : boolean := false;
    ENABLE_I2S_TO_AXIS : boolean := true;
    ENABLE_AXIS_TO_I2S : boolean := true;
    VENDOR_TAG : string := "GENERIC";
    PRODUCT_SERIES_TAG : string := "GENERIC"
  );
  port (
    m_axis_tdata : out std_logic_vector(AXIS_DATA_WIDTH - 1 downto 0);
    m_axis_tvalid : out std_logic;
    m_axis_tready : in std_logic;
    m_axis_tlast : out std_logic;
    s_axis_tdata : in std_logic_vector(AXIS_DATA_WIDTH - 1 downto 0);
    s_axis_tvalid : in std_logic;
    s_axis_tready : out std_logic;
    s_axis_tlast : in std_logic;
    clk : in std_logic;
    rstn : in std_logic;
    reg_wr_addr : in std_logic_vector(REG_ADDR_WIDTH - 1 downto 0);
    reg_rd_addr : in std_logic_vector(REG_ADDR_WIDTH - 1 downto 0);
    reg_wr_en : in std_logic;
    reg_rd_en : in std_logic;
    reg_data_in : in std_logic_vector(REG_DATA_WIDTH - 1 downto 0);
    reg_data_out : out std_logic_vector(REG_DATA_WIDTH - 1 downto 0);
    reg_wr_rdy : out std_logic;
    reg_rd_rdy : out std_logic;
    reg_wr_valid : out std_logic;
    reg_rd_valid : out std_logic;
    reg_error : out std_logic;
    i2s_mclk_i : in std_logic;
    i2s_mclk_o : out std_logic;
    i2s_mclk_oe : out std_logic;
    i2s_bclk_i : in std_logic;
    i2s_bclk_o : out std_logic;
    i2s_bclk_oe : out std_logic;
    i2s_lrck_i : in std_logic;
    i2s_lrck_o : out std_logic;
    i2s_lrck_oe : out std_logic;
    i2s_sdata_i : in std_logic;
    i2s_sdata_o : out std_logic;
    i2s_sdata_oe : out std_logic
  );
end component;

Direct Entity Instantiation

u_radif_i2s_axis : entity radhdl.radif_i2s_axis
  generic map (
    SAMPLE_WIDTH       => 24,
    AXIS_DATA_WIDTH    => 64,
    REG_DATA_WIDTH     => 32,
    REG_ADDR_WIDTH     => 16,
    DEFAULT_MCLK_DIV   => 1,
    DEFAULT_BCLK_DIV   => 7,
    DEFAULT_LRCK_BITS  => 32,
    USE_EXTERNAL_MCLK  => false,
    NO_MCLK            => false,
    USE_EXTERNAL_BCLK  => false,
    ENABLE_I2S_TO_AXIS => true,
    ENABLE_AXIS_TO_I2S => true,
    VENDOR_TAG         => "GENERIC",
    PRODUCT_SERIES_TAG => "GENERIC"
  )
  port map (
    m_axis_tdata  => <m_axis_tdata_signal>,
    m_axis_tvalid => <m_axis_tvalid_signal>,
    m_axis_tready => <m_axis_tready_signal>,
    m_axis_tlast  => <m_axis_tlast_signal>,
    s_axis_tdata  => <s_axis_tdata_signal>,
    s_axis_tvalid => <s_axis_tvalid_signal>,
    s_axis_tready => <s_axis_tready_signal>,
    s_axis_tlast  => <s_axis_tlast_signal>,
    clk           => <clk_signal>,
    rstn          => <rstn_signal>,
    reg_wr_addr   => <reg_wr_addr_signal>,
    reg_rd_addr   => <reg_rd_addr_signal>,
    reg_wr_en     => <reg_wr_en_signal>,
    reg_rd_en     => <reg_rd_en_signal>,
    reg_data_in   => <reg_data_in_signal>,
    reg_data_out  => <reg_data_out_signal>,
    reg_wr_rdy    => <reg_wr_rdy_signal>,
    reg_rd_rdy    => <reg_rd_rdy_signal>,
    reg_wr_valid  => <reg_wr_valid_signal>,
    reg_rd_valid  => <reg_rd_valid_signal>,
    reg_error     => <reg_error_signal>,
    i2s_mclk_i    => <i2s_mclk_i_signal>,
    i2s_mclk_o    => <i2s_mclk_o_signal>,
    i2s_mclk_oe   => <i2s_mclk_oe_signal>,
    i2s_bclk_i    => <i2s_bclk_i_signal>,
    i2s_bclk_o    => <i2s_bclk_o_signal>,
    i2s_bclk_oe   => <i2s_bclk_oe_signal>,
    i2s_lrck_i    => <i2s_lrck_i_signal>,
    i2s_lrck_o    => <i2s_lrck_o_signal>,
    i2s_lrck_oe   => <i2s_lrck_oe_signal>,
    i2s_sdata_i   => <i2s_sdata_i_signal>,
    i2s_sdata_o   => <i2s_sdata_o_signal>,
    i2s_sdata_oe  => <i2s_sdata_oe_signal>
  );

Generics

NameTypeDefaultDescription
SAMPLE_WIDTHpositive24Sample width per left/right channel.
AXIS_DATA_WIDTHpositive64AXI-Stream payload width. The low half carries right-channel data and the high half carries left-channel data.
REG_DATA_WIDTHpositive32Width of the RADIF register data bus.
REG_ADDR_WIDTHpositive16Width of the RADIF register address bus.
DEFAULT_MCLK_DIVnatural1Default MCLK half-period divider. Ignored when GENERATE_MCLK is false.
DEFAULT_BCLK_DIVnatural7Default BCLK half-period divider used when USE_EXTERNAL_BCLK is false.
DEFAULT_LRCK_BITSpositive32Default number of BCLK rising edges per LRCK half-frame.
USE_EXTERNAL_MCLKbooleanfalseUse the external MCLK pin as a timing reference indicator instead of generating MCLK.
NO_MCLKbooleanfalseDisable MCLK generation and leave MCLK output released.
USE_EXTERNAL_BCLKbooleanfalseUse the external BCLK/LRCK pins for I2S timing instead of generating them.
ENABLE_I2S_TO_AXISbooleantrueEmit I2S-to-AXIS receive datapath logic.
ENABLE_AXIS_TO_I2SbooleantrueEmit AXIS-to-I2S transmit datapath logic.
VENDOR_TAGstring"GENERIC"Selects the vendor-specific implementation path. This core is portable RTL for all values.
PRODUCT_SERIES_TAGstring"GENERIC"Identifies the target FPGA family for generated project metadata.

Ports

NameDirectionTypeDescription
m_axis_tdataoutstd_logic_vector(AXIS_DATA_WIDTH - 1 downto 0)AXI-Stream output generated from received I2S stereo frames.
m_axis_tvalidoutstd_logicAXI-Stream output valid.
m_axis_treadyinstd_logicAXI-Stream output ready.
m_axis_tlastoutstd_logicAXI-Stream output frame marker.
s_axis_tdatainstd_logic_vector(AXIS_DATA_WIDTH - 1 downto 0)AXI-Stream input consumed for I2S transmit stereo frames.
s_axis_tvalidinstd_logicAXI-Stream input valid.
s_axis_treadyoutstd_logicAXI-Stream input ready.
s_axis_tlastinstd_logicAXI-Stream input frame marker.
clkinstd_logicFPGA/register clock domain.
rstninstd_logicActive-low reset for the FPGA/register clock domain.
reg_wr_addrinstd_logic_vector(REG_ADDR_WIDTH - 1 downto 0)Register write address.
reg_rd_addrinstd_logic_vector(REG_ADDR_WIDTH - 1 downto 0)Register read address.
reg_wr_eninstd_logicOne-cycle register write request.
reg_rd_eninstd_logicOne-cycle register read request.
reg_data_ininstd_logic_vector(REG_DATA_WIDTH - 1 downto 0)Register write data.
reg_data_outoutstd_logic_vector(REG_DATA_WIDTH - 1 downto 0)Register read data.
reg_wr_rdyoutstd_logicRegister write ready.
reg_rd_rdyoutstd_logicRegister read ready.
reg_wr_validoutstd_logicRegister write response valid.
reg_rd_validoutstd_logicRegister read response valid.
reg_erroroutstd_logicRegister address or runtime error.
i2s_mclk_iinstd_logicExternal MCLK input when USE_EXTERNAL_MCLK is true.
i2s_mclk_ooutstd_logicGenerated MCLK output when enabled.
i2s_mclk_oeoutstd_logicMCLK output-enable. A value of 1 enables the generated MCLK output.
i2s_bclk_iinstd_logicExternal BCLK input when USE_EXTERNAL_BCLK is true.
i2s_bclk_ooutstd_logicGenerated BCLK output when USE_EXTERNAL_BCLK is false.
i2s_bclk_oeoutstd_logicBCLK output-enable. A value of 1 enables the generated BCLK output.
i2s_lrck_iinstd_logicExternal LRCK input when USE_EXTERNAL_BCLK is true.
i2s_lrck_ooutstd_logicGenerated LRCK output when USE_EXTERNAL_BCLK is false.
i2s_lrck_oeoutstd_logicLRCK output-enable. A value of 1 enables the generated LRCK output.
i2s_sdata_iinstd_logicI2S serial data input.
i2s_sdata_ooutstd_logicI2S serial data output.
i2s_sdata_oeoutstd_logicSerial data output-enable. A value of 1 enables the generated serial data output.

Register Interfaces

Static register maps are rendered below for this module.

InterfaceDirectionsSignalsRepresentative ports
M_AXISin, out4m_axis_tdata, m_axis_tvalid, m_axis_tready, m_axis_tlast
S_AXISin, out4s_axis_tdata, s_axis_tvalid, s_axis_tready, s_axis_tlast
Register control/statusin, out11reg_wr_addr, reg_rd_addr, reg_wr_en, reg_rd_en, reg_data_in, reg_data_out, reg_wr_rdy, reg_rd_rdy, +3 more

Register Maps

radif_i2s_axis

Source: interfaces/hdl/radif/register_maps/radif_i2s_axis.map.json

Controls I2S receive/transmit enables, generated clock dividers, LRCK framing, and transfer counters.

RegisterOffsetAccessResetDescription
control0x00rw0x00000000Controls the enabled audio datapaths and clears the software-visible transfer counters.
status0x04ro0x00000000Reports active transfer state and elaboration-time clocking modes for the I2S bridge.
mclk_div0x08rwDEFAULT_MCLK_DIVGenerated MCLK divider used when the core owns MCLK generation.
bclk_div0x0CrwDEFAULT_BCLK_DIVGenerated BCLK divider used when the core owns BCLK/LRCK generation.
lrck_bits0x10rwDEFAULT_LRCK_BITSConfigures the generated LRCK frame length.
rx_count0x14ro0x00000000Counts stereo frames emitted by the I2S-to-AXI-Stream receive path.
tx_count0x18ro0x00000000Counts stereo frames consumed by the AXI-Stream-to-I2S transmit path.

control

Offset 0x00 / Access rw / Reset 0x00000000

Controls the enabled audio datapaths and clears the software-visible transfer counters.

Control[15:0]
1514131211109876543210
RSVD [15:3]
CLEAR
AXIS TO I2S EN
I2S TO AXIS EN
Control[31:16]
31302928272625242322212019181716
RSVD [31:16]
NameRegister bit(s)Description
CLEARControl[2]Writing 1 clears RX_COUNT, TX_COUNT, and any sticky status bits. Software should write this as a pulse and then restore the desired enable bits.
AXIS TO I2S ENControl[1]Enables the I2S serial transmit path. When set, AXI-Stream input frames are accepted and shifted out as left/right I2S samples.
I2S TO AXIS ENControl[0]Enables the I2S serial receive path. When set, completed left/right I2S samples are packed into AXI-Stream output frames.

status

Offset 0x04 / Access ro / Reset 0x00000000

Reports active transfer state and elaboration-time clocking modes for the I2S bridge.

Status[15:0]
1514131211109876543210
RSVD [15:11]
NO MCLK MODE
EXT BCLK MODE
EXT MCLK MODE
RSVD [7:1]
ACTIVE
Status[31:16]
31302928272625242322212019181716
RSVD [31:16]
NameRegister bit(s)Description
NO MCLK MODEStatus[10]Set when the core was elaborated with NO_MCLK true and the generated MCLK output is disabled.
EXT BCLK MODEStatus[9]Set when the core was elaborated with USE_EXTERNAL_BCLK true and BCLK/LRCK are sampled from external pins.
EXT MCLK MODEStatus[8]Set when the core was elaborated with USE_EXTERNAL_MCLK true.
ACTIVEStatus[0]Set while an RX AXI-Stream frame is waiting to be accepted or a TX AXI-Stream frame is loaded for serial output.

mclk_div

Offset 0x08 / Access rw / Reset DEFAULT_MCLK_DIV

Generated MCLK divider used when the core owns MCLK generation.

MclkDiv[15:0]
1514131211109876543210
MCLK DIV [15:0]
MclkDiv[31:16]
31302928272625242322212019181716
RSVD [31:16]
NameRegister bit(s)Description
MCLK DIVMclkDiv[15:0]MCLK half-period divider. The generated MCLK output toggles every MCLK_DIV + 1 FPGA clock cycles when USE_EXTERNAL_MCLK and NO_MCLK are both false.

bclk_div

Offset 0x0C / Access rw / Reset DEFAULT_BCLK_DIV

Generated BCLK divider used when the core owns BCLK/LRCK generation.

BclkDiv[15:0]
1514131211109876543210
BCLK DIV [15:0]
BclkDiv[31:16]
31302928272625242322212019181716
RSVD [31:16]
NameRegister bit(s)Description
BCLK DIVBclkDiv[15:0]BCLK half-period divider. The generated BCLK output toggles every BCLK_DIV + 1 FPGA clock cycles when USE_EXTERNAL_BCLK is false.

lrck_bits

Offset 0x10 / Access rw / Reset DEFAULT_LRCK_BITS

Configures the generated LRCK frame length.

LrckBits[15:0]
1514131211109876543210
LRCK HALF FRAME BITS [15:0]
LrckBits[31:16]
31302928272625242322212019181716
RSVD [31:16]
NameRegister bit(s)Description
LRCK HALF FRAME BITSLrckBits[15:0]Number of BCLK rising edges in each LRCK half-frame. Typical I2S operation uses the sample slot width, such as 32 for 24-bit audio in 32-bit slots.

rx_count

Offset 0x14 / Access ro / Reset 0x00000000

Counts stereo frames emitted by the I2S-to-AXI-Stream receive path.

RxCount[15:0]
1514131211109876543210
RX FRAME COUNT [15:0]
RxCount[31:16]
31302928272625242322212019181716
RX FRAME COUNT [31:16]
NameRegister bit(s)Description
RX FRAME COUNTRxCount[31:0]Monotonic count of completed left/right stereo frames presented on M_AXIS. Cleared by CONTROL.CLEAR or reset.

tx_count

Offset 0x18 / Access ro / Reset 0x00000000

Counts stereo frames consumed by the AXI-Stream-to-I2S transmit path.

TxCount[15:0]
1514131211109876543210
TX FRAME COUNT [15:0]
TxCount[31:16]
31302928272625242322212019181716
TX FRAME COUNT [31:16]
NameRegister bit(s)Description
TX FRAME COUNTTxCount[31:0]Monotonic count of AXI-Stream stereo frames accepted and shifted out on I2S. Cleared by CONTROL.CLEAR or reset.

Testbenches

tb_radif_i2s_axis interface timing diagram

Source: interfaces/hdl/radif/testbenches/tb_radif_i2s_axis.vhd

Exercises the I2S/AXI-Stream bridge in internally clocked loopback mode. The waveform shows register-controlled clock dividers, generated MCLK/BCLK/LRCK, AXI input acceptance, I2S serial output, looped-back serial input, and AXI output frame generation.

Interface Timing Diagram

Source: interfaces/hdl/radif/testbenches/tb_radif_i2s_axis.vhd

clk
i2s_bclk_i
i2s_bclk_o
i2s_bclk_oe
i2s_mclk_i
i2s_mclk_o
i2s_mclk_oe
rstn
reg_rd_valid
reg_wr_valid
i2s_sdata_i
i2s_sdata_o
i2s_sdata_oe
reg_data_in
reg_data_out
reg_rd_addr
reg_wr_addr
i2s_lrck_i
i2s_lrck_o
i2s_lrck_oe
reg_error
reg_rd_en
reg_rd_rdy
reg_wr_en
reg_wr_rdy
M_AXIS
S_AXIS
M_AXIS interface signals

M_AXIS Interface Waveform

Source: interfaces/hdl/radif/testbenches/tb_radif_i2s_axis.vhd

m_axis_tlast
m_axis_tready
m_axis_tvalid
m_axis_tdata
S_AXIS interface signals

S_AXIS Interface Waveform

Source: interfaces/hdl/radif/testbenches/tb_radif_i2s_axis.vhd

s_axis_tlast
s_axis_tready
s_axis_tvalid
s_axis_tdata

Sources