MADI transceiver
Project: MADI transceiver | |
---|---|
Featured: | |
State | Active |
Members | Danny Witberg |
GitHub | No GitHub project defined. Add your project here. |
Description | This project descibes a MADI transceiver in VHDL |
Picture | |
No project picture! Fill in form Picture or Upload a jpeg here |
Contents
Introduction
The Multichannel Audio Digital Interface or MADI protocol is a way to send multiple digital audio channels over a single transmission line. The protocol describes up to 64 channels of up to 24 bit audio at a sample rate of 48kHz. The sample rate can be higher at the expense of the number of channels, so up to 32 channels of 96kHz sampled audio is also a possibility. With the S-MUX protocol, even higher sample rates can be achieved with putting consecutive samples in adjacent channels. This project describes an implementation of the MADI protocol with the use of an FPGA in the VHDL language.
MADI protocol
The MADI protocol is based on the not-so-popular-anymore FDDI protocol, which was a networking protocol. MADI was invented by the AES or Audio Engineering Society back in 1991, and became known as the AES10 standard. The line speed or symbol speed of MADI is 125Mbps, while the transmission speed is 100Mbps. The difference is because of a line encoding scheme known as 4B5B, which converts 4 incoming bits into 5 outgoing bits. Also, for synchronisation purposes, there is a special bit sequence. A MADI datastream consists of a continuous flow of frames, each carrying up to 64 channels. The maximum length of a frame is equal to the sampling rate, because between frames, the synchronisation symbol is sent. Each channel has 4 mode bits, 24 bits representing the audio data, and 4 other bits used for other purposes. So, a total of 32 bits is needed for a channel. The maximum effective transmission speed is 32 bits x 64 channels x 48000Hz is 98304000 bits per second or 98.304Mbps. This leaves a minimum of 1.696Mbps for synchronisation.
MADI decoding
To decode a MADI stream you will need to extract the data bits out of the stream. MADI is NRZI encoded, meaning a '0' is sent as no signal change, and a '1' is sent as a change in the signal. There are a couple advantages to this. First of all, the maximum signal transition rate of the data signal is 62.5MHz, meaning cheaper hardware can be used that don't have to handle with a 125MHz signal. Second, the actual level of the signal does not matter, only changes in the signal has to be detected.
The symbol speed of MADI is 125Mbps and is pretty high compared to the nominal speeds that cheap FPGA's are capable of. Also, the clock signal is not transmitted with the data, so we only know that the symbol speed is ABOUT 125Mbps. We can not simply feed a 125MHz signal to a data latch and input our stream data. A speed variance of only 25ppm (parts-per-million) means we would be missing 3125 bits every second! To succesfully extract all the data bits out of the stream, we would have to do one of two things: 1) Determine the exact clock rate of the datastream or 2) Oversample the stream to make sure we get all the data. The first solution is mostly an analog process, involving a Phase Locked Loop (PLL) and a good analog filter to extract the clock signal out of the datastream. Since the FPGA is all digital logic, we can not use this solution. The second solution means we have to sample the incoming signal at a much higher rate than the transmission speed. Oversampling factors of 6 and higher is no luxury! 125MHz x 6 is 750MHz and that would instantly turn the implementation of this design onto an FPGA to a very expensive project!
Multi Phase Deserialising
We can still implement the decoding of the MADI stream in an FPGA thanks to a very cool feature of the PLL inside of the FPGA. Inside the FPGA, there is a PLL to convert an incoming clock into a derative clock signal. For example, we can convert an incoming 25MHz signal into a 5 times higher frequency of 125MHz. The PLL has a number of outputs, and each of those outputs is capable of outputting the frequency at a different phase. This is the feature we need for oversampling the MADI datastream! The Altera Cyclone II we intended to use has 3 outputs for each PLL, C0, C1 and C2. We can output the same clock speed at the C1 output as the C0 output, but at a 60 degrees phase advance compared to the C0 output. If we set the C2 output at 120 degrees advance, we have basically 6 phases we can detect.
Count the sampling moments
Now that we have a parallel signal representation of our incoming datastream, we can count the bits that the incoming datastream stays the same. What use does this have? Well, if we know for how long the incoming stream stays the same, we know how many '0' bits have been transmitted before the change (meaning a '1') has been sent. The best way to discriminate this is by means of bit buckets. If you are using a 6x oversampling scheme, you could say if 5 to 7 bits stayed the same before the signal changed, a '1' had been sent. from 11 to 13 bits, a "01" has been sent, etc. The way the MADI symbols are encoded, the maximum amount of '0's sent before a '1' is 4. This means that we only have to create bit buckets for '0', "01", "001", "0001" and "00001". There are no other possibilities.
Accumulate the incoming bits
Since we now have way to extract the actually sent databits out of our stream, we can focus on alignment and decoding. MADI uses a distinct synchronization bit pattern, which is known as "JK" in 4B5B terms. This bitpattern of "11000 10001" we have to look out for in our incoming bits. Note that there is a '1' at the end of this pattern, meaning that, at the moment this pattern is received, we are in alignment. This is important because we con only decode a '0' or a stream of '0's at the moment that it is followed by a '1'.
Decoding the bitstream
After we are aligned, we know that we have to decode bits by groups of 5. We can use a counter to count how many bits are received. If the counter is under 5, we can not decode yet. If it is 5 exactly, we can decode 1 symbol, and reset the counter. But if it is more than 5 bits, we have to decrease the counter by 5, and get the last 5 bits.