01signal.com

A brief introduction to 8b/10b encoding, 64b/66b, 128b/130b etc.

This page is the third in a series of pages introducing the Multi-Gigabit Transceiver (MGT).

Introduction

The application logic's data stream is almost never transmitted on the physical channel as is. Doing so will most likely cause the MGT to malfunction, for the reasons shown previously. In almost all applications, the MGT or the application logic applies an encoding to the data stream in order to ensure that the physical channel can operate properly. This encoding also assists with the synchronization between the transmitter and the receiver.

This page goes through the basics of the most commonly used encoding techniques. The list of protocols on the previous page connects between these encodings and protocols used between FPGAs.

8b/10b encoding

8b/10b encoding is used by several protocols, for example some versions of PCIe, Gigabit Ethernet, SATA, Displayport and SuperSpeed USB. All FPGA MGTs have a built-in 8b/10b encoder and decoder, even though this encoder can be implemented in the logic fabric as well.

This encoding translates each byte (8 bits) into a word consisting of 10 bits. The main purpose of this translation is to create a sequence of bits that has the same number of '0' and '1' on the average. In other words, the bits in the encoded data stream are DC-balanced. Another advantage is that the encoding ensures that there are enough transitions between '0' and '1' in the data stream, so that the CDR (Clock Data Recovery) mechanism can work properly.

Note however that 8b/10b encoding doesn't randomize the data stream. In particular, the 8b/10b encoding alone is not sufficient if an equalizer is used, and this equalizer requires that the data stream is statistically random.

In order to achieve the DC-balance goal, some of the 8-bit words can be encoded into two possible candidates. For example, the 8-bit word 0x20 (00100000, denoted D0.1) can be encoded as either 1001111001 or 0110001001. Both alternatives are decoded back to 0x20. Note that the first alternative has four '0' bits and six '1' bits. The second alternative has six '0' bits and four '1' bits. This is the whole idea with the 8b/10b encoding: The encoder has two alternatives, one alternative with more '0' than '1', and the other way around with the second alternative.

The encoder uses this feature to ensure the balance between '0' and '1' in the long run: It remembers if there has been too many '0' or too many '1' in the data stream so far. This imbalance is called Running Disparity. The encoder chooses the 10-bit word that helps reducing this imbalance.

Not all 8-bit words have two 10-bit candidates. For example, the 8-bit word 0x23 (00100011, denoted D3.1) is always encoded into 1100011001. This encoded word has the same number of '0' and '1', so it doesn't influence the Running Disparity.

This encoding was first published in 1983, and has been very popular in protocols that were introduced until roughly year 2010. It is less popular in recently published protocols. The main reason is that a scrambler is often part of the protocol as well. The data stream's DC balance is hence guaranteed by the use of the scrambler, so the 8b/10b encoding is not required for this purpose. The scrambler also ensures that transitions between '0' and '1' occur often enough. On the other hand, the 8b/10b encoding adds 25% more bits for transmission to the physical channel. These extra bits could have been used to transmit useful data.

That said, some successful protocols that use a scrambler also use 8b/10b. For example, all versions of PCIe require using a scrambler, however 8b/10b encoding is also used in PCIe versions below 3.0. So 8b/10b encoding obviously has some other benefits. And this brings us to the next topic: K-symbols.

K-symbols

The fact that an 8b/10b encoder generates 10 bits from each 8 bits it encodes, means that the encoded word has 1024 possible combinations, in comparison with the 256 possibilities that the original word has. Even if we assumed that each original word has two possible encoded words, this would cover 512 possibilities. As mentioned early, some of the 8-bit words only have one 10-bit word candidate for translation, so there are less than 512 possibilities for the 10-bit words. The conclusion is hence that at least 512 possibilities of 10-bit words don't have a corresponding 8-bit word.

Hence 8b/10b encoding is able to detect bit errors on the physical link, by virtue of detecting 10-bit words that are illegal. FPGA MGTs have output ports that are used to inform the application logic when an illegal 10-bit word is detected. This error detection mechanism isn't very valuable however, as it doesn't detect all errors.

The really valuable feature of 8b/10b encoding is K-symbols. A K-symbol is encoded and transmitted instead of an 8-bit word. The decoder is able to distinguish between a regular data word and a K-symbol, and there is always a method to inform the application logic when a K-symbol arrives.

So 8b/10b encoding allows the transmitter to send extra information on the data channel in a way that isn't confused with regular data. This feature is often used by protocols in order to help the receiver synchronize with the transmitter's data stream.

The meaning of the K-symbols depends on the protocol. There are however two K-symbols that are used by many protocols with the same meaning:

Both of these are explained in more detail below.

When 8b/10b is enabled on an FPGA MGTs, the interface with the application logic has a separate wire for each byte of data. This wire indicates if the data is a regular data byte or if it's a K-symbol. In other words, the interface for transmitting data allows choosing whether each transmitted word is a piece of regular data or a K-symbol. That said, when a data word is marked as a K-symbol, the 8-bit data word is limited to only these options:

Byte value (hex) K-Symbol
1C K28.0
3C K28.1
5C K28.2
7C K28.3
9C K28.4
BC K28.5
DC K28.6
FC K28.7
F7 K23.7
FB K27.7
FD K29.7
FE K30.7

Likewise for the MGT receiver, the is a separate wire for each received byte in the interface with the application logic. Each such wire's value indicates if the related byte should be interpreted as plain data or as a K-symbol. The receiver also has special functionality for treating K28.5 (Comma Symbol, COM) and K28.0 (Skip symbol, SKP) in special ways. These two K-symbols are discussed next.

The Comma symbol (K28.5)

The 10-bit representation of K28.5 is 0011111010 or 1100000101. This word is particularly useful, because this sequence of bits can only appear on the physical channel as a result of transmitting K28.5. The receiver doesn't need to be synchronized with the transmitter in order to detect a K28.5: It's enough that the last 10 bits that were received match one of these two words.

This makes K28.5 an excellent tool for synchronizing the receiver. Once this K-symbol has been detected, the boundaries of the other 10-bit words are known.

FPGA MGTs have the capability to automatically align the arriving data stream in response to the arrival of a K28.5 symbol. Usually, it's also possible to request that the alignment is made with regards to a larger boundary. For example, the MGT can be configured to align an arriving K28.5 to the beginning of a 32-bit word.

Aside from aligning the receiver, the K28.5 symbol can also be used to align other functional units that need synchronization. For example, the protocol may request that the scrambler is reset in response to the arrival of this K-symbol.

Because of these possibilities, protocols often require that a K28.5 is transmitted periodically for the purpose of synchronizing the receiver. Protocols that establish a connection with a handshake often use K28.5 as part of the link establishment. Either way, the K28.5 symbol often simplifies the design of the protocol to the extent of justifying the 25% extra bits that are transmitted on the physical channel.

The Skip symbol (K28.0)

In most practical situations, there is a difference between the clock frequencies of the transmitter and the receiver. This can cause a problem: Often, the interface between the MGT and the application logic is synchronous with the receiver's own local clock. So the data arrives according to the transmitter's clock, but is delivered to the application logic according to the receiver's clock.

In other words, the data that an MGT receives arrives at a pace that is dictated by the other side. But the local clock dictates how fast the data is consumed.

If the transmitter's clock frequency is higher, the result is that the application logic fetches data from the MGT too slowly. The surplus data will accumulate eventually, and an overflow will occur somewhere inside the MGT. On the other hand, if the transmitter's clock frequency is lower, the application logic wants to fetch data faster than it arrives. This too is a problem.

A simple solution to this problem is adding "skip symbols". For example, the SuperSpeed USB protocol defines a "SKP Ordered Set" as two consecutive K28.0 symbols. The protocol requires that these two K28.0 are transmitted once for every 354 regular data words. The receiver MGT is allowed to discard these K28.0 symbols instead of presenting them to the application logic. This solves the problem of surplus data when transmitter's clock is faster than the receiver's clock: When the receiver MGT begins to accumulate data because of the clock frequency differences, it skips the arriving K28.0 symbols.

With this mechanism, the transmitter may transmit 356 words at the same time period as the receiver's application logic fetches only 354 words. With the calculation 356 / 354 ≈ 1.00565, it follows that this mechanism can cover up for a frequency difference of up to ~0.565% between the two clocks. This is more than the protocol's specification allows, of course.

The receiver's MGT is also allowed to add K28.0 symbols to an existing "SKP Ordered Set". This can help when the transmitter's clock is slower. This means that the application logic at the receiving side attempts to fetch data faster than it arrives. The MGT is hence allowed to fill up the missing data slots with K28.0 symbols: The application logic is expected to ignore all K28.0 symbols anyhow.

The PCIe protocol uses the Skip Symbol is a similar way. PCIe's format of SKP Ordered Set is different, and it consists of four K-symbols: First a K28.5 (Comma), and then three K28.0 symbols. The principles of using the skip symbol are nevertheless the same.

64b/66b encoding

As already mentioned, 8b/10b encoding uses the physical channel inefficiently, and the main purposes of this encoding (DC balancing and ensuring transitions between '0' and '1') aren't required when a scrambler is used. This is why more recent protocol rely on 64b/66b encoding and similar methods. It's however important to note that 64b/66b isn't really an encoding method. Rather, it's a method for organizing the data stream and control words. The data isn't encoded into a different representation. All that happens is that the data is organized into segments, and extra bits are inserted in order to allow synchronization and sending control information across the channel.

Note that K-symbols are part of the 8b/10b encoding only, and are not available in any of the other coding formats.

64b/66b encoding is used by several protocols, for example 10G/100G Ethernet. It's worth nothing that the advanced versions of PCIe and USB are based on other methods, as discussed below.

The 64b/66b encoding divides the data stream into 64-bit segments, and adds two bits at the beginning of each such segment. Hence each segment is 66 bits long on the physical channel. These two bits extra have one of two possible values: "01" or "10". If these two bits are "01", the 64-bit word that follows contains eight bytes of data. If these bits are "10", the next byte contains a code that defines what the rest of the 56 bits contain: How many data words and how many control words.

The control words are used in particular to indicate the start and end of frames (packets), but also to insert idle words for the purpose of compensating for clock frequency differences (similar to 8b/10b's skip symbols). Control words that are specific to a protocol can also be defined.

As already mentioned, if the first two bits are "10", the rest of the 64 bits are divided into two parts: An 8-bit code word and 56 bits consisting of a combination of data and control words. The organization of the data and control words inside the 56-bit segment is quite complicated, mainly because each control word is 7 bits long. This peculiarity is necessary for allowing to insert eight control words into the remaining 56 bits.

In addition, protocols that use this encoding also use a scrambler for the data for the purpose of ensuring DC-balance and randomness of the data. This randomness is required not just for the equalizer's sake: The receiver also needs this in order to find the beginning of the 66-bit segments in the arriving data stream. This is done by examining the first two bits in each segment of 66 bits. If this pair of two bits only have the values "01" or "10" repeatedly, the receiver is synchronized. Otherwise, it needs to try a different position. The scrambler ensures that the other bits are random, so if the receiver is misaligned, a "00" or "11" will appear instead of the legal combinations soon enough.

So all in all, 64b/66b makes a better use of the underlying physical channel, however a protocol that uses this method is more difficult to implement. In particular, the need to handle each segment differently (depending on the first two bits and possibly also on the eight bits that follow) adds complication to the implementation. Different FPGA MGTs offer different levels of assistance in this matter. In particular, some MGTs have a built-in mechanism that automatically aligns the receiver with the 66-bit segments of the arriving data. The application logic is nevertheless responsible for the more difficult task of unpacking 66-bit segments that contain a combination of data and control words.

An FPGA MGT is likely to have a built-in gearbox for extracting 64-bit words from the stream of 66-bit segments. Gearboxes are discussed further in the next page of this series.

64b/67b, 128b/130b and 128b/132b

Even though 64b/66b makes a better use of the physical channel, this method is complicated to implement. This is probably the reason that the protocols for both PCIe and SuperSpeed USB took a different path when they went away from 8b/10b.

Both of these protocols remained with the idea that the data stream is divided into segments. Instead of 64-bit segments, these protocols are based upon 128 bits.

PCIe 3.0 and later is based upon 128b/130b. Similar to 64b/66b encoding, each 128-bit segment of this protocol starts with either "01" or "10" in order to distinguish between data and control codes. SuperSpeed USB Gen 2 is based upon 128b/132b. Each of its 128-bit segments start with either "0011" or "1100" for the same purpose. The only difference is that the USB protocol allocates four bits instead of two for a better protections against bit errors.

Also similar to 64b/66b encoding, a scrambler is used on the 128-bit part of each segment in order to ensure DC-balancing and randomization of the data stream. But this is where the similarity with 64b/66b ends: Both protocols define the meaning of the content of the 128-bit part according to the protocol's own structure. Hence 128b/130b and 128b/132b only stand for the division of the data stream into segments, and how many bits are added to the part that contains data. The rest is specific to each protocol.

64b/67b encoding works in a similar way. The difference is that three bits are added to each segment of 64 bits, for the same purposes. This encoding is used primarily by the Interlaken protocol.

No encoding

It's possible to implement a communication link without any of the encoding methods mentioned above. An example of such protocol is xillyp2p, which uses a synchronization word every 223 bits for the purpose of aligning and synchronizing the receiver with the transmitter. To this protocol, the MGT is just a SERDES. The main advantage of this strategy is that the protocol doesn't depend at all on the MGT's other features. This simplifies the implementation of the protocol on a wide range of MGTs.

The disadvantage is that the FPGA logic resources are used for something that possibly could have been done inside the MGT.

This approach is eligible when the protocol covers all needs that the encoding may help with: DC-balancing, randomizing (when needed), synchronization and word alignment as well as distinction between data and control information.

Summary

As shown above, there are different approaches to encoding the application logic's data stream, and it's also possible to not use any encoding at all. For most applications, 8b/10b encoding is easiest to work with, but this encoding is wasteful in relation to the physical channel's data stream. This is why more recent protocols have adopted other encoding methods that are more efficient, but considerably more difficult to use.

This wraps up the third page in this series about MGTs. The next page introduces the some parts of the PCS, among others the parts that implement the encodings mentioned here.

Copyright © 2021-2024. All rights reserved. (b4b9813f)