Skip to the content
PCBKitNew board
4 layers99 × 55 mmAes50 trion, the printed circuit board in 3D

An IP-Core for AES50 protocol

Size
99 × 55 mm
Copper layers
4
Thickness
1.6 mm
Parts
213
Nets
175
Pads
681
Tracks, vias
2,030, 401
Pours
41
Routed
Yes
KiCad
KiCad 10.0 (file 20260206)
Created
23 Dec 2025
Updated
31 Oct 2026

Overview

Aes50 trion is an open-source printed circuit board by YetAnotherElectronicsChannel, from the YetAnotherElectronicsChannel/AES50 repository on GitHub, published under the GPL-3.0 licence. It is a 4-layer board of 99 × 55 mm with 213 parts on 175 nets, routed with 2,030 tracks and 401 vias.

It is built around the T20Q100F3C4. Its parts include 112 resistors, 56 capacitors, 10 diodes, 8 ICs and 4 connectors. It belongs with the interfaces and adapters boards of this library.

Main components

1

README

README.md

AES50 VHDL IP

An implementation of the AES50 protocol in vanilla VHDL.

About the IP

I started developing this IP around end of 2024 - originally with some other intention.
However I decided to make this project public with the purpose to be used in the fabulous OpenX32 project.
Therefore, this IP was developed fully independent/separated from the OpenX32 project and comes instead with a reference implementation on a custom PCB (also included in this repo) designed around an Efinix Trion T20 FPGA.
Integration into the OpenX32 project is still a to-do work.. But I'm sure those guys will manage :)

IP version 2

At the end of October 2026, I published a resource-optimized, functionally compatible version of this IP core, targeting the constrained FPGAs of the OpenX32 project: AES50v2

AES50 Specification

Before asking any detailed questions about functionality or implementation of this IP, please make sure you read and understood the public available AES50 specification which can be downloaded here.
Otherwise I might not answer to your request.

Features of the IP

  • Audio-Formats
    • 48kHz / 24-Bit
    • 44.1kHz / 24-Bit
  • Audio-Interfaces
    • TDM-8 (6x In + 6x Out) for full 48x48 channel access
    • I2S (1x In + 1x Out) for a reduced 2x2 channel access (the other 46x46 channels are ignored)
  • Support for Aux-Data-Tunnel (which is e.g. used for headamp control) over TDM or UART
    • Tunnels the auxiliary data channel through the TDM interface
    • Send and receive data to/from the auxiliary data tunnel via UART
  • Operation Modes
    • AES50-Master + TDM/I2S Master (Timing Reference: Local Oscillator)
    • AES50-Master + TDM/I2S Slave (Timing Reference: External I2S/TDM Device)
    • AES50-Slave + TDM/I2S Master (Timing-Reference: External AES50 Device)
  • PLL Support
    • Integrated I2C-controller and driver for Cirrus Logic CS2100CP PLL
  • Compatibility / Real-Life Tested
    • Proven to work with X32, Wing, S- and DL- series stageboxes
    • Flawless handling of Cat-Cable Hot-Plugging

IP Internal Structure

AES50 IP Internal Structure

Use Case A: 48x48 Channel with Multi-TDM8 Interface and Aux-Data via Uart

48x48 Channel Use-Case

Use Case B: 2x2 Channel with simple I2S Interface and Aux-Data via Uart

2x2 Channel Use-Case

Use Case C: 48x48 Channel with Multi-TDM8 Interface and Aux-Data via TDM8

48x48 Channel Use-Case

Top-Module Ports Description

SignalDirectionTypeDescription
clk50_iinstd_logic50 MHz Clock for the Ethernet Logic
clk100_iinstd_logic100 MHz Clock for the Core Logic
rst_iinstd_logicSynchronous Reset (100 MHz clock-domain)
fs_mode_iinstd_logic_vector(1 downto 0)Sample-Rate Select
  • 00 → 44.1 kHz
  • 01 → 48 kHz
  • 10 → n.a.
  • 11 → n.a.
sys_mode_iinstd_logic_vector(1 downto 0)System-Mode Select
  • 00 → AES50 Slave & I2S/TDM Master
  • 01 → AES50 Master & I2S/TDM Master
  • 10 → AES50 Master & I2S/TDM Slave
  • 11 → n.a.
tdm8_i2s_mode_iinstd_logicInterface Select
  • 0 → 48x48 TDM8 (Support for Aux-over-TDM)
  • 1 → 2x2 I2S (only Aux-over-UART)
aux_tx_tdm_uart_select_iinstd_logicAux-Data-Mode
  • 0 → Aux-over-TDM
  • 1 → Aux-over-UART
rmii_crs_dv_iinstd_logicRMII Data Valid Receive from PHY
rmii_rxd_iinstd_logic_vector(1 downto 0)RMII Data from PHY
rmii_tx_en_ooutstd_logicRMII Data Valid Transmit to PHY
rmii_txd_ooutstd_logic_vector(1 downto 0)RMII Data to PHY
phy_rst_n_ooutstd_logicPHY Reset (active low)
aes50_clk_a_rx_iinstd_logicAES50 Clock A Receive
aes50_clk_a_tx_ooutstd_logicAES50 Clock A Transmit
aes50_clk_a_tx_en_ooutstd_logicAES50 Clock A Enable LVDS Output Driver
aes50_clk_b_rx_iinstd_logicAES50 Clock B Receive
aes50_clk_b_tx_ooutstd_logicAES50 Clock B Transmit
aes50_clk_b_tx_en_ooutstd_logicAES50 Clock B Enable LVDS Output Driver
clk_1024xfs_from_pll_iinstd_logicClock from external PLL (1024× fs)
pll_lock_n_iinstd_logicExternal PLL Lock Status (active low)
clk_to_pll_ooutstd_logicClock to external PLL
pll_mult_value_ooutnaturalExternal PLL multiplication-factor
pll_init_busy_iinstd_logicPLL init busy status
mclk_ooutstd_logicMaster Clock (256x fs) - derived (divided by x4) from PLL - independent of System-Mode Select
wclk_ooutstd_logicWord Clock Output (if our IP is I2S/TDM Master)
bclk_ooutstd_logicBit Clock Output (if our IP is I2S/TDM Master)
wclk_readback_iinstd_logicWord Clock Readback (direct from FPGA-Pin - always needed)
bclk_readback_iinstd_logicBit Clock Readback (direct from FPGA-Pin - always needed)
wclk_out_en_ooutstd_logicWord Clock Output Enable (high if IP is I2S/TDM Master)
bclk_out_en_ooutstd_logicBit Clock Output Enable (high if IP is I2S/TDM Master)
tdm_iinstd_logic_vector(6 downto 0)6x TDM8 Data Input + 1x TDM8 Aux Data Input (only needed in 48x48 mode)
tdm_ooutstd_logic_vector(6 downto 0)6x TDM8 Data Output + 1x TDM8 Aux Data Output (only needed in 48x48 mode)
i2s_iinstd_logicI2S Input (only needed in 2x2 mode)
i2s_ooutstd_logicI2S Output (only needed in 2x2 mode)
aes_ok_ooutstd_logicAES50 Link Status (high when connection established)
dbg_ooutstd_logic_vector(7 downto 0)Various internal debug signals
uart_ooutstd_logicUART output (received data from the AES50 AUX tunnel)
uart_iinstd_logicUART input (data to send over AES50 AUX-tunnel)

Aux Data Tunnel

AES50 provides (as part of the protocol) an auxiliary data channel with a fixed bandwidth of roughly 5 Mbit/s (the exact rate depends on the selected sample rate, as the auxiliary data stream is synchronous with the audio transmission).
According to the AES50 specification, there was a proposal (though not mandatory) to use standard Ethernet frames that could be tunneled through this auxiliary data channel - (ever wondered about the mysterious Ethernet port on the DN9630?) -> Therefore I assume that this proposed approach using virtual Ethernet frames is also used in other AES50 devices on the market.
However, additional mechanisms are required to transmit Ethernet frames through the auxiliary channel - specifically bit-stuffing and data-scrambling.

Aux Data over TDM

Since the bitstream is synchronous with the audio transmission, this IP enables sending and receiving the aux-bitstream over the TDM8 interface.
Internally, the IP handles the bitstream as 16-bit words, and the TDM module distributes the auxiliary data evenly across the eight TDM slots as 24-bit “samples.”
The extra 8 bits act as an overlay protocol to ensure correct interpretation of the auxiliary words when tunneling them over a 3rd party audio-transportation-medium.
If the TDM-Aux-RX/TX pins of two instances of this IP are cross-connected, it allows transparent tunneling of the auxiliary data channel as long as synchronicity and bit-consistency is ensured.
A similar concept appears to be implemented in the Appsys Multiverter, which tunnels AES50 auxiliary data as eight audio channels through a Dante network to maintain head-amp remote control.

  • See further details in the TDM module implementation
Aux Data over UART

It is also possible to send and receive data over the aux-data-tunnel with a UART connection.
See here an example print-out of a Wing-Rack connected.
Example UART Printout

Head Amp Remote Control Example

A small Arduino example shows how to self-identify and remotely control the head amps (gain & phantom power) of AES50 devices.

This example uses a Raspberry Pi Pico (RP2040), which acts as a command bridge between a computer and the UART terminal connected to the FPGA/AES50 IP core.
The device identifies itself as an X32 Full-Size and the head amps can be controlled via a serial terminal using the following command examples:

  • gain:ch1@20 → Sets gain on channel 1 to +20 dB
  • phantom:ch5@1 → Enables +48V on channel 5
  • phantom:ch5@0 → Disables +48V on channel 5

The gain-ranges may be interpreted differently with different devices. You will find some info in the comments of the code-example.
This example is currently configured for controlling a Wing. Make sure that Remote-HA-Control over AES50 is enabled in the console settings.

See more information here: Unofficial Protocol Description

Special thanks to Christian Nöding for reverse-engineering the proprietary protocol and Thomas Zint (Behringer R&D) for helping with the checksum calculation.

Note: The transmission of channel-names does not work yet.

Audio Interface Timing

Warning: When this IP is in I2S/TDM slave-mode (sys_mode_i = "10"), make ultimately sure, that BCLK/WCLK is stable before releasing the IP's reset.
AES50 protocol has a pulse-width modulation mechanism in the outgoing (LVDS-)clock signals which needs to be synchronized to the incoming I2S/TDM clock.
This is only done once after reset. You must ensure externally, if WCLK/BCLK has changed or was unstable, this IP core runs again through a new reset.

I2S

In I2S mode, BCLK is 64*fs : 32-Bit per Slot (24-Bit Audio + 8 Bit Padding).
3.072 MHz for 48k mode and 2.8224 MHz for 44k1. No other I2S configuration is supported besides this.
This is valid for all system-modes.

TDM-8

BCLK is supposed to be 12.288 MHz for 48k or 11.2896 MHz for 44k1 : 32-Bit per Slot (24-Bit Audio + 8 Bit Padding).
No other TDM configuration is supported besides this.
This is valid for all system-modes.

TDM-8 Master Timing (when BCLK/WCLK is output)

When the IP is TDM master, the WCLK will be high for 8 BCLK cycles. TDM8 Master Timing

TDM-8 Slave Timing (when BCLK/WCLK is input)

WCLK must be only high for one BCLK pulse (but can be longer of course) TDM8 Slave Timing

Misc

Deviations against the specification
  • Bit-Error correction is only implemented on the transmitting side (as AES50 devices on market expects this to be implemented properly), however this IP does not correct bit-errors on receiving side. (I personally don't see this as a critical feature. Basically no other network audio protocol has this implemented)
  • AES50 specifies a delay of around 3 sample times IP in- to output (in 44k1, 48k). However this IP processes the audio-samples internally in frames of 6 samples at 48k or 11 samples at 44k1. Therefore the latency is slightly higher
  • Clock integrity check: AES50 by default runs the LVDS-clock-signals (through the CAT-wire) bidirectional. Even though it would be technically enough to run the clock only unidrectional from the clock-master to the clock-slave, AES50 uses this to check the integrity of the clock-recovery (PLL) on the AES50-slave-device side. As I understood, the slave-device would be supposed to regenerate the pulse-width modulated clock signal based on the recovered clock and send it back to the master. However this IP just loops the clock back to the master in case it is in slave-configuration. Also as per spec, the AES50 should verify the clock speeds for correctness. This IP has implemented only a more simple timeout-watchdog alike clock integrity checking (on both clock-transmitting and clock-receiving side).
  • AES50 also supports other audio-formats and sample-rates (e.g. Bitstream-Audio, 88k2, 96k, etc..). This IP is only usable for 24-Bit PCM-Audio for 44k1 and 48k. However the IP is prepared for later integration of 88k2 and 96k sample-rate. I just didn't do this because I was lacking of suitable devices which support AES50 with 88k2/96k.
  • The original AES50 implementation found in commercial devices also seem to differ against the specification (or I understood the specification wrong) in two points I found out so far (by actually reverse engineering it):
    • The figures for aux-data-packet scrambler / descrambler in the specification seem to be exchanged against each other. The actual data-scrambler is the logic-structure shown in the descrambler-figure and vice-versa
    • In 48k mode, one LC-segment (352 Bits) should consist of in sum 12 LC-sub-segments with two multiplexed channels of 6 samples each having 2-bit padding after each LC-subsegment and 4-bit padding at the end of the LC-frame. According to my calculations, one LC-subsegment should be 27-bits long (12* (27Bit LC-Subsegment + 2-Bit Padding))+4-Bit Padding = 352 Bit. However the actual protocol behaves like: (6* (26-Bit LC-Subsegment + 2-Bit Padding + 28-Bit LC-Subsegment + 2-Bit Padding)) + 4-Bit Padding = 352 Bit.
TODOs / next steps / not done yet
  • Verification of internal clock domain crossings
  • Constraining and verification of input- & output timings (RMII, TDM, etc..)
  • Bit Transparency Testing
  • Refactoring of TDM SerDes
  • Implement 88k2/96k mode
  • Check why the Arduino Code-Example is not transmitting channel-names correctly.
Random Info
  • The core-clock of this IP can also run at a reduced clock-speed of 80 MHz (instead of 100 MHz) if I2S mode only is used. Some internal timing-reference values must be changed for this (see in the top VHDL module in the efinity project)
  • In case, the IP will be used in sys_mode_i="01" (AES-master + TDM/I2S master) only, the external PLL is not necessarily needed and the IP can be tricked to run from a static oscilator with 1024xfs speed. Connect the static 1024xfs clock to "clk_1024xfs_from_pll_i", make "pll_init_busy_i" and "pll_lock_n_i" to static '0' and just leave "clk_to_pll_o" and "pll_mult_value_o" open.
  • sys_mode_i, fs_mode_i and tdm8_i2s_mode_i should not be changed on the fly. If this is changed, the IP needs a new reset.
  • Spot the easter-egg in this project :-)

Test Board Setup

Overview

In I2S mode, only I0/O0 will be used as in+out.
Board Overview

Front View

Board Front View

FPGA Resource Utilization

This is the resource utilization for a full configuration (all sample-rates and operation modes supported, dual TDM/I2S support, PLL-I2C driver etc.).
Resource utilization depends on actual used configuration.
Especially if core is configured for e.g. I2S only operation, the utilization is reduced drastically (the TDM-Serdes is still a rather resource-inefficient implementation as of today).

Reference FPGA: Efinix Trion T20Q100F3 (Speedgrade: 4) using Efinity 2025.1.110.5.9 toolchain.
FPGA Resource Utilization

Some technical implementation hints

Ram Reorder processes in AES50-TX/RX Modules

RAM Reorder Process

Startup Sequencing

The Startup Sequencing must be timed very precisely.
The Ethernet frame containing the "2048x ASSM-marker" in the header must be tightly aligned with the modulated-clock-pulses on the LVDS signaling.
This happens in 48k as follows: The IP waits until the clock-pulse-modulation happens. (It is assumed it will happen again after 2048x WCLK). When the clock-pulse-modulation happened, a timer starts with the duration of approx. 2042x (2048-6) WCLK timeframes.
Then the TDM-serializer starts recording samples into the FIFO to the AES50-TX-module.
The AES50-TX-Module waits until 6 samples (basically 288 samples as it is 6 samples * 48 channels) are in the FIFO.
The first ethernet-frame transmitted after this startup-sequence will contain the ASSM-marker in the frame-header and will be aligned with the 2048x modulated clock-pulse.
This also explains the mysterious "first_transmit_counter" values on the top-level files.
Startup Sequencing
In 44k1 the same mechanism applies, but with a duration of 2048-11 = 2037 WCLK cycles wait time.

Testbenches

I also attached now the testbenches I used.
Please see the testbenches as WIP as I modified them as needed and those testbenches might not work out of the box. So this is more of a "playground" rather than a professional verification testbench.

License

Copyright (c) 2025 Markus Noll (YetAnotherElectronicsChannel)

This IP core is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This IP core is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this IP core. If not, see https://www.gnu.org/licenses/.

Any other use — including use in other projects or commercial applications — is not permitted without a separate written license agreement.

Third-party components included in this repository may be licensed under different terms (for example, GPLv3). These components retain their original licenses and are clearly marked in the source header.

Parts

213
QtyValueFootprintReferences
5010k/0402Resistor_SMD:R_0402_1005MetricR13, R14, R15, R16, R18, R20, R100, R101, R102, R103, R104, R106, R108, R110, R111, R112 +34
35100n/16V/0402Capacitor_SMD:C_0402_1005MetricC1, C2, C10, C11, C12, C13, C14, C15, C18, C19, C20, C21, C22, C23, C24, C26 +19
18100/0402Resistor_SMD:R_0402_1005MetricR47, R52, R53, R54, R55, R56, R57, R58, R60, R62, R63, R64, R65, R66, R67, R68 +2
1633/0402Resistor_SMD:R_0402_1005MetricR5, R6, R7, R8, R24, R29, R48, R59, R61, R70, R71, R72, R73, R83, R84, R86
101k/0402Resistor_SMD:R_0402_1005MetricR12, R19, R27, R28, R46, R49, R50, R81, R105, R109
10TestPointTestPoint:TestPoint_Pad_D1.0mmTP1, TP2, TP3, TP4, TP5, TP6, TP7, TP8, TP9, TP10
922u/25V/0805Capacitor_SMD:C_0805_2012MetricC40, C43, C44, C47, C50, C51, C54, C55, C56
81u/50V/0603Capacitor_SMD:C_0603_1608MetricC4, C16, C17, C25, C29, C32, C36, C46
449.9/0402Resistor_SMD:R_0402_1005MetricR1, R2, R3, R4
475/0603Resistor_SMD:R_0603_1608MetricR10, R11, R22, R23
4LED 0603 Red (C2286)LED_SMD:LED_0603_1608MetricD3, D4, D5, D8
4LED 0805 Green (C2297)LED_SMD:LED_0805_2012MetricD1, D6, D7, D10
2100/0805Resistor_SMD:R_0805_2012MetricR25, R30
2100k/0402Resistor_SMD:R_0402_1005MetricR90, R107
212k/0402Resistor_SMD:R_0402_1005MetricR17, R74
222k/0402Resistor_SMD:R_0402_1005MetricR87, R88
222p/50V/0402Capacitor_SMD:C_0402_1005MetricC42, C49
24k7/0402Resistor_SMD:R_0402_1005MetricR79, R80
2600Ω/0603 (C1002)Inductor_SMD:L_0603_1608MetricFB1, FB2
2FH2.54-09-07PZD (C7500776)MarkusFootprintLibrary:FH2.54-09-07PZDJ2, J4
2FHD4020S-2R2MT (C602029)Inductor_SMD:L_APV_ANR4020L1, L2
2HX1188NLT (C9363)MarkusFootprintLibrary:HX1188NLTR1, TR2
2SN65MLVD206DR (C2671006)Package_SO:SOIC-8_3.9x4.9mm_P1.27mmU2, U3
2SY8089AAAC (C78988)Package_TO_SOT_SMD:SOT-23-5U7, U8
2SolderJumper_2_OpenJumper:SolderJumper-2_P1.3mm_Open_RoundedPad1.0x1.5mmJP1, JP2
110u/10V/0603Capacitor_SMD:C_0603_1608MetricC37
11n/2kV/1206Capacitor_SMD:C_1206_3216MetricC6
125MHz (C7431317)Oscillator:Oscillator_SMD_ECS_2520MV-xxx-xx-4Pin_2.5x2.0mmX2
1CS2100CP-CZZR (C2663267)Package_SO:MSOP-10_3x3mm_P0.5mmU6
1DSWB04LHGET (C99418)MarkusFootprintLibrary:DSWB04LHGETSW2
1LAN8720A (C45223)Package_DFN_QFN:VQFN-24-1EP_4x4mm_P0.5mm_EP2.5x2.5mm_ThermalViasU1
1LED 0805 Yellow (C2296)LED_SMD:LED_0805_2012MetricD2
1MMBT5551 (C2145)Package_TO_SOT_SMD:SOT-23Q1
1Neutrik NE8FAH (C368497)MarkusFootprintLibrary:Neutrik NE8FAHX1
1PZ254-2-20-Z-2.5-G1 (C18198015)Connector_PinHeader_2.54mm:PinHeader_2x20_P2.54mm_VerticalJ1
1SS34 40V 3A (C8678)Diode_SMD:D_SMAD9
1Standard Header 2.54mmConnector_PinHeader_2.54mm:PinHeader_1x09_P2.54mm_VerticalJ3
1T20Q100F3C4Package_QFP:LQFP-100_14x14mm_P0.5mmU4
1TLV803SDBZR (C132016)Package_TO_SOT_SMD:SOT-23U5
1TS-1187A-B-A-B (C318884)MarkusFootprintLibrary:TS-1187A-B-A-BSW1

Questions

How big is the Aes50 trion PCB?

It measures 99 × 55 mm and has 4 copper layers, 1.6 mm thick.

What parts does the Aes50 trion use?

213 parts, built around the T20Q100F3C4. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Aes50 trion KiCad files?

From the YetAnotherElectronicsChannel/AES50 repository on GitHub, at the commit this page was made from: the board is Hardware Design/KiCad Files/aes50_trion.kicad_pcb and its schematic Hardware Design/KiCad Files/AES50_FrontEnd.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Aes50 trion design in my own project?

Its repository publishes it under the GPL-3.0 licence: you may reuse it on that licence's terms (keep the author's notice, and for a copyleft licence share your changes alike).

Similar boards

  • 4 layers75 × 71 mmLa pod, the printed circuit board in 3D

    La pod

    azonenberg/starshipraider

    Open hardware test equipment

    213 parts193BSD-3-Clause
  • 4 layers70.8 × 110 mmPipes main, the printed circuit board in 3D

    Pipes main

    shannon-greenlight/pipes

    8 Harmonic tracking oscillator

    213 parts2
  • 4 layers170.1 × 100.5 mmLattePandaMU carrier custom 20260226, the printed circuit board in 3D

    LattePandaMU carrier custom 20260226

    tuankoko567/LattePanda-MU-carrier-Board

    Designing high-speed carrier board using KiCad, applying differential pair routing and length matching, studying impedance control and PCB stack-up planning, learning signal integrity and EMI-aware layout techniques.

    213 parts2
  • 4 layers35 × 35 mmCanonical, the printed circuit board in 3D

    Canonical

    AnasSarkiz/smart-nema14-motor-controller

    STEPPERONLINE 14HM11-0404S controller — unrouted work-in-progress prototype; mechanical and electrical qualification pending

    213 parts
  • 4 layers159.9 × 99.9 mmMoto board, the printed circuit board in 3D

    Moto board

    devtank-ltd/kicad_hiltop_moto_board

    KiCAD files for Moto card for HILTOP

    213 parts
  • 4 layers180 × 130 mmShield, the printed circuit board in 3D

    Shield

    Nicolboy/KICAD-C2000-powershield

    Shield d'isolation, alimentation et interconnexion pour TMS320 C2000, conçu sous KiCad 10.

    213 partsCERN-OHL-S-2.0
  • 4 layers178 × 169.6 mmLinePCB, the printed circuit board in 3D

    LinePCB

    Team-Elite-2026/LinePCB2026

    212 parts