//////////////////////////////////////////////////////////////////////////////////////////////////////////
//// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
//////////////////////////////////////////////////////////////////////////////////////////////////////////


//------------------------------------------------------------------------------
// I2S Peripheral Top Level Module
// 
// This module provides a complete I2S audio interface with:
// - Variable sample rates (8K to 192K Hz)
// - Variable sample widths (8, 16, 24, 32 bits)
// - AXI-Stream host interface for both TX and RX
// - APB configuration interface
// - Support for I2S, Left/Right Justified, and PCM formats
//------------------------------------------------------------------------------

module i2s_top
  import apb_pkg::*;
  import i2s_pkg::*;
#(
  parameter AXI_DWIDTH     = 32,           // Host AXI-Stream data width
  parameter I2S_DWIDTH     = 32,           // I2S data width (max sample size)
  parameter TX_FIFO_DEPTH  = 1024,        // TX buffer depth
  parameter RX_FIFO_DEPTH  = 1024,        // RX buffer depth
  parameter APB_ADDR_WIDTH = 12,           // APB address space width
  localparam AXI_KWIDTH    = AXI_DWIDTH/8  // AXI-Stream keep width
)(
  //----------------------------------------------------------------------------
  // Clock and Reset
  //----------------------------------------------------------------------------
  input                     i_apb_clk,        // APB clock domain
  input                     i_apb_rst,        // APB reset (active high)
  input                     i_ref_clk,        // Reference clock for PLL
  input                     i_axis_clk,       // AXI-Stream clock domain
  
  //----------------------------------------------------------------------------
  // APB Configuration Interface
  //----------------------------------------------------------------------------
  input  apb_m2s            i_apb_m2s,        // APB interface 
  output apb_s2m            o_apb_s2m,        // APB interface 
  
  //----------------------------------------------------------------------------
  // Host AXI-Stream TX Interface (Host to I2S)
  //----------------------------------------------------------------------------
  input                     i_tx_axis_tvalid, // TX data valid
  input  [AXI_DWIDTH-1:0]   i_tx_axis_tdata,  // TX data
  input  [AXI_KWIDTH-1:0]   i_tx_axis_tkeep,  // TX data keep
  input                     i_tx_axis_tlast,  // TX packet boundary
  input                     i_tx_axis_tuser,  // TX user signal
  output                    o_tx_axis_tready, // TX ready
  
  //----------------------------------------------------------------------------
  // Host AXI-Stream RX Interface (I2S to Host)
  //----------------------------------------------------------------------------
  output                    o_rx_axis_tvalid, // RX data valid
  output [AXI_DWIDTH-1:0]   o_rx_axis_tdata,  // RX data
  output [AXI_KWIDTH-1:0]   o_rx_axis_tkeep,  // RX data keep
  output                    o_rx_axis_tlast,  // RX packet boundary
  output                    o_rx_axis_tuser,  // RX user signal
  input                     i_rx_axis_tready, // RX ready
  
  //----------------------------------------------------------------------------
  // I2S Physical Interface
  //----------------------------------------------------------------------------
  output                    o_i2s_bclk,       // I2S bit clock output
  output                    o_i2s_lrclk,      // I2S L/R clock (word select)
  output                    o_i2s_sdata_tx,   // I2S serial data output
  input                     i_i2s_sdata_rx,   // I2S serial data input
  output                    o_i2s_mclk_out,   // I2S mclk output
  
  //----------------------------------------------------------------------------
  // Status and Interrupts
  //----------------------------------------------------------------------------
  output                    o_tx_underrun,    // TX FIFO underrun
  output                    o_rx_overrun,     // RX FIFO overrun
  output                    o_pll_locked,     // Clock PLL locked status
  output                    o_irq             // Interrupt request
);





//put a blank line above


`pragma protect begin_protected
`pragma protect version=1
`pragma protect author="NVIDIA"
`pragma protect author_info="HOLOLINK"
`pragma protect encrypt_agent="Radiant encrypt_hdl"
`pragma protect encrypt_agent_info="Radiant encrypt_hdl Version 1.0"

`pragma protect encoding=(enctype="base64", line_length=64, bytes=256)
`pragma protect key_keyowner="Lattice Semiconductor"
`pragma protect key_keyname="LSCC_RADIANT_2"
`pragma protect key_method="rsa"
`pragma protect key_block
H6KDGI3MKaxCdlI8X2FHW281oMa6ckvZSZG31qVXl+nCERd+8+WUp+thIaTAgYqU
N/Mie2gPA7TfX02RcZtHYKbzQQ8Nogv03hmoFSy03pxU69VO1Rt/HyycCVm9Uy8h
VP+6stT5bws9vaXbhv6aPpCFTOiN36mh9RAUkkOTuRah4hln2t0vMFLoB9VNBYFK
/7GQu+i5oDWg5p/lL0bjxEE5IbHZ9rxZhdqmcjOQZGTfELZx+nJD0vGRb/vM8hnJ
1lUdK2TMApmPPWygNOyLWugJr+PeR9UDH8wwRzXD8/tpmRjHnTbWyEOclV2XPxi7
rFjGb3B9ptkBThOigpZPQQ==

`pragma protect encoding=(enctype="base64", line_length=64, bytes=128)
`pragma protect key_keyowner="Synopsys"
`pragma protect key_keyname="SNPS-VCS-RSA-1"
`pragma protect key_method="rsa"
`pragma protect key_block
Rf36psQKU/LZC8bTxPWtFG4Q75+kYhAUmxkm7/meupLbHTPqEP4j1ViBcSJydfiB
O4tRFwUYTINHAHHXyldNmAx+UbwDqJAusF92PctDXU0f2I4oOTSUEiz+HGXaZSxJ
72+0hwqU5Pj+/XB6ta1dh5vTJ0VTSphR7W45pZGm8qk=

`pragma protect encoding=(enctype="base64", line_length=64, bytes=256)
`pragma protect key_keyowner="Intel Corporation"
`pragma protect key_keyname="Intel-FPGA-Quartus-RSA-1"
`pragma protect key_method="rsa"
`pragma protect key_block
1qIE8kZsoGvT7FTT4CxlXzJdoIZx1AF5YyEAu7rpSWBjc3Kj4WmqyVUnxG7GGDS/
Y/mNhf91z92nUwvQInvg7Jk2+D8F9MtkIlUTlfiEIIzfr4Q8Zq+4raG1tsgOn8AD
ITzl4vAeW8Sc00S9X/Z86kQqqAUrNmsoKch1euQVE8iKmqnVcKUIxyztKlbR6NuT
2SWdFZKxgFLLUawzQiUfcnfaWCj4N4IZjNaHzZliKHAXVj1NrdAWunbRJnTmog/r
51u69ZMDhov9RRjk4DkApYWPfL1QKP94utmN5hNL58qpEnv6kL+kYP7t+1HEQ3Ol
uo7w8e7VtqiCk12ywVLFrA==

`pragma protect encoding=(enctype="base64", line_length=64, bytes=256)
`pragma protect key_keyowner="Xilinx"
`pragma protect key_keyname="xilinxt_2019_02"
`pragma protect key_method="rsa"
`pragma protect key_block
Exhxr2Sm1jZ9Gy8wORN9kVpKoqA9NjVz1W/RPCEeYkgGwhsXzV4T1M/JK5OyL2z1
5bMGhR54esdFISkcvD3u3KIPDfnVRj/mUj0rAiwlYQxGSm20W7Q14FoUGcZBZmYG
4wGn/gyzSyqmJv91Il3hUEmF3iqW22v64P04e73MVtoRF9TIJagZANo9tWZ0Um/u
Y/olj5JmrQTOn90UJnDNrPDY+4OgqBwLu5nV10MxxlAirK7Ua3G/IlF53OXvLECX
/+GRNFC8oIxNcW2Q6mnmr7H/csoMrcxLqJVwE3+Nmlofr8Yl+IIef8r9nKUoesx0
TbYQtdAFf3YJQVVMUumfcg==

`pragma protect encoding=(enctype="base64", line_length=64, bytes=256)
`pragma protect key_keyowner="Synplicity"
`pragma protect key_keyname="SYNP15_1"
`pragma protect key_method="rsa"
`pragma protect key_block
eU6rc9aLu3ShAJv9owtKLKzsJjouzhvoQvAsZwM3ZlGFmdEzUGYi+51ogFZ3oiP2
z1gUpq+Sr4diOeRULbsKhClexhu23cAydOj2GU/lHLMuBbOUNrj+sbmsM6uMoGeg
eI7w0+3ubdLgJEZ53TF7wz+Tjy4v9ksWV8yRoeRLlKHvYMpwywwDIfRy303DSaX/
d2p6yEixVfDCbmdGNAnUN114r3HCy/dUcBPmdsuqLVeI0BpHNIyYoRjWw/OkuDH6
bFFm/lIaPQvLPsAWZnA1S15+vWCamR2ts/oJc/lrwYtcYwycaEcQOzms+1qi5BYm
M6Xkq17JHFHp1GjW5k8GEA==

`pragma protect encoding=(enctype="base64", line_length=64, bytes=256)
`pragma protect key_keyowner="Synplicity"
`pragma protect key_keyname="SYNP05_001"
`pragma protect key_method="rsa"
`pragma protect key_block
Yq+5e1OJBTcPUnDgkqCRcHJjokqV6eI78ySYl+ocvWwbhbQfzBzI1e6mSmXDt+mj
hArvvJYf3R0uQxlYHVoBo7NNtX9AAr6e0uk9E77jyvLpnfMmiX9x/TihGee8JRsc
ZadvBlzOaOPA86s0JvOQYy41aBv2gRKlBO42bbKO/YTAvyBRf3zVsYBXGQWXSjZL
2QKj6ndM8lcGHCTGOyTaGq9mM5Cu+IQ7ZNqh+0MZ9aWml0y5kiYr/9Mu8eDr9p2l
5w0sLuwTyS3Xc9F6/veJqat1lRvOr0NRrHZ/G0RWxVAa2fpdSWS+ZcuvXdtT5y06
ZWykFpXr7RyxaQtm9T3B2w==

`pragma protect encoding=(enctype="base64", line_length=64, bytes=960)
`pragma protect key_keyowner="Microsemi Corporation"
`pragma protect key_keyname="MSC-IP-KEY-RSA"
`pragma protect key_method="rsa"
`pragma protect key_block
FiX3ETZIY5IGH/1zTqUlhik1lzLTVqBYIcMFmoLKgDMuJ60FxrBbXbAcvfpo1uaH
wxmaXfHQzDPGZNE3EzE9L43Rv+TE4U0Z9iIYrvYCopG+3wLSkAI3dfXEJWbqyPrc
UBv0QW331AMN0rem+Ya/X67O0hnm/YScQb8fIVZJP1h8CaCyUMo2LrWsr/V2e/gM
ibfxIyIo9WPSwSoGX92rczxVrUctuZGmmaCqHPdvoBy1ektm7jba2YQ5vv3kbmxd
b000f9vVa9wgWZYRlFWOtcHqSTECWqTDYqS+tnJPQWT1MZKO+4iH38dTSd/vi8fP
wO/N37YC+8XxGRmtZ5QSTKIcrjj6TUKRugILp/+HHDPEXc/Y23NfRZkzCxZcDX7A
Kf84/+BmgEA+CnilgAzZQmecM2Flx8FDny8mEQPN9H/Di88pUE8H138Nm9wQaGV1
bB/p9TKL98PYqnXmEMU+ZDwlW/6rJakIJstMGZSLo/76HcLPi7tq5qwhByOKp9bf
aV/wwdhw74zWebIn4t/0bevgJamf1Mb/obgPvHMMcuKP36kKL7zcOyPJGkPEIgak
AMEZDITqXGMheQeYFKNiY/rQrkZMz1mCRpqcgPJQL6xG0x2d953CzKUcdJyPCaJe
KM/loZOZ4WJ44U0jpgVHXh1kyXpUdcIVdwFgvrzbnFfqpQDiesIh3Duu0k7qoFNk
F3t4qzKJICgRIb8lPnuSc06W4F7SHwN22w2ViYmVgFxLr7af0qA+0oVfFcX+UJML
CN5ZEkYUjgccLlUdiv0p3EobuxUFOw7FW3zWtsIG8n1OsYUzA7pPR76hTgPk7QBB
WJgzD/OtV64cTgnlKeITU9/hiEAYXmxSQACBp2/HHsA6/umQ4WVD0213weAS7092
2eKjVLgqwkbwkFuaN9CLs+RgOLNM1xux0Ke9yUszAj6oGGFNw4TPRHUtwJv9zgH2
LKZFxnhg5AlmiNePwu3rwfqN1EI/yK+MAXE6BwMeW6V5DKbXJQV7nN13b3PvfXO1
SX3z1QtAbWt52QOQiDTCndZJ29luRxTeTT7xLkXaF/d7yUlHl0OH+t2Qb2BA3+go
VclSnVOgRPPDHWiTNUnxo6x58kGM9hd437T3KmlU/LqQUZg+RMB7HFspZHQJ+/fX
vKtL5qrNfOFCakM0vCerF2bblk8VUjKugXr1pmJMvP48O7cwOmmPbi3EpAg1gpgz
zB638P2QgcZ89StfLi9G8K0RQrcAYGTqMaxOTElDFtrD21gj4CECTUkoVAmRcUNp

`pragma protect encoding=(enctype="base64", line_length=64, bytes=128)
`pragma protect key_keyowner="Mentor Graphics Corporation"
`pragma protect key_keyname="MGC-VERIFSIM-RSA-1"
`pragma protect key_method="rsa"
`pragma protect key_block
VC1J8v+PE4RigMRwgi9vPnSifnAOnQeVReY8RvlEN/0l2Vw+5AZh1YGHfcGg4F0a
nWI5I6rfO4QtRMV8c8nGExB9NPNlSE0w/A3ZO+i8n3lKOGIQ8VrZVXbwB/N8LbfH
imq5ZtukCjqRW73X4kWL//ncv4nlQrDstWFCb8yM66U=

`pragma protect data_method="aes128-cbc"
`pragma protect encoding=(enctype="base64", line_length=64, bytes=10192)
`pragma protect data_block
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
5BN5Q2CK7SJeQmxy7AnFxA==

`pragma protect end_protected

endmodule 
