Therefore, my maximum allowable encoded bitstream is 30.722Mbps, exactly 1.25x of 24.576Mbps data rate. This allows me to use 8b/10b.
64/66b is great, but it seems like it's fairly complicated, and I rather reuse my existing IPs.
How is this for a coding scheme? It isn't as nice as 8b/10b, but it seems to meet your needs (simple, 15 values in 5 bits, can be AC coupled, small to implement)
A 4b/5b codingStart with a running disparity (DP) of -1.
Map your fifteen raw values onto fifteen 5-bit symbols, depending on the current value of the running disparity DP:
DP is + / DP is - Change in DP
S0 => 00000 / 11111 -5 / +5
S1 => 00001 / 11110 -3 / +3
S3 => 00010 / 11101 -3 / +3
S3 => 00011 / 11100 -1 / +1
S4 => 00100 / 11011 -3 / +3
S5 => 00101 / 11010 -1 / +1
S6 => 00110 / 11001 -1 / +1
S7 => 11000 / 00111 -1 / +1
S8 => 01000 / 10111 -3 / +3
S9 => 01001 / 10110 -1 / +1
S10 => 10100 / 01011 -1 / +1
S11 => 01100 / 10011 -1 / +1
S12 => 10010 / 01101 -1 / +1
S13 => 10001 / 01110 -1 / +1
S14 => 10000 / 01111 -3 / +3
It helps to make sure that S0 is the most common symbol in the data stream.
Note: Just found this is flawed, so don't use it - framing can be ambiguousYou will note that one pair of 5-bit symbols is missing:
SERR => 01010 / 10101 -1/+1 INVALID
How to frame the data on receiving end- When you see 0000011111 or 1111100000 (two S0s in a row) you have confirmed framing, this can only occur with two S0 symbols are in a row.
- When you see no SERR symbols, then it is pretty likely (but not certain) that you have the correct framing,
- When you see a SERR you should bitslip by one bit
Framing is lost- When disparity falls out of out of bounds (it should stay between -4 and +4), but the RX should limit to +/-8 as it doesn't know when to start)
- That can be simplified to "when you see 00000-000xx" or "11111-111xx", to avoid keeping track of disparity
- When you see any SERR symbols
Benefits- DC balanced
- Data stream can be inverted by TX and/or RX without any issues
- Run length limited (to eight bits at a glance), so clock recovery possible.
- Encoding is very simple, a four bit register for DP value, and a 4-to-5-bit LUT (for the symbol) and a 4-to-4 bit LUT for the change in disparity, and a four bit signed adder.
- Basic decoding is very simple, ideal for the small lookup tables (a 5-to-4 bit LUT for decode, a 5-to-1 bit LUT for the "valid symbol signal" and a few bits of state
- Only a small FSM and shift register is needed to control bit-slipping to get the framing sorted - Lock if you see 00000-11111 or 11111-00000, (two S0 symbols are seen in a row), and maybe if no SERR is seen for a few thousand symbols), unlock if SERR, 00000-000xx or 11111-111xx is seen, and bitslip if SERR is seen.
- No multiplications or divisions needed in encoding or decoding
- Any unexpected glitches in the encoder or decode will flush out very quickly, as there is minimal state being tracked