The brand new PAM3 version drops the flip bits because they are not required anymore: the scrambling combined with the non-binary encoding and the "Same" symbol make the droop problems (almost) vanish.
Error detection remains a big issue, particularly since the format has shrunk from 20b to 18b per frame and the only means to detect errors is only the mark bits. gPEAC will catch the rest but with a delay that remains to be determined.
The ParPop unit checks parity as well as H8 errors. The binary/NRZi version uses both to ensure integrity and I don't want to let this go so a new version is adapted, using both parity and H8.
ParPop "rotates" the mark with the parity while the 2 Flip bits get inserted in the word directly. The new version does not flip anything but uses these bits to "rotate" the mark again. Hence the new name : ParRot.
That's TWO ternary additions now, and the critical datapath has increased but the PAM3 pipeline is a little bit slower, if only because gPEAC requires two damned cycles instead of one for the PEAC16×2 version, but it's still fine. At 10MB/s, that's 5MHz, which is enough time to take a coffee break.
3 codes for parity is very little but it's still better than a single bit and should catch at least 2/3rds of the trivial errors, before the slower gPEAC catches up.
--------------------------------
So CircuitJS lets me adapt the ParPop circuit into the ParRot circuit:

In this early version, I am lazy : I simply copy-pasted the "half adder + ternary adder" to include the contribution from the individual popcounts.
I should obviously try to make a ternary popcount (adding pA, pB, qA and qB) then only do the 2+2 ternary add. The above circuit works and is a rough approximation of the final circuit but a ternary popcount would remove some gates.
Or maybe, simply, create a ternary 2+2+2 adder !
-----------------
Another more radical approach is to ditch parity and check for... wait for it ! Yes, ternarity. I am clueless for now but I'll find a way, because if parity is relatively simple, the whole popcount takes some resources.
Doing the Popcount directly in ternary is tedious. CircuitJS shows that 2-in gates yield a compression factor of less than 1.5 per logic stage, so there are like 5 stages for counting 4 inputs. OTOH, when limiting to 2 stages, the thing requires like a dozen of 4-input gates and a couple of 6-in gates... Just for counting 4 bits !
Working with pairs of bits is convenient in some ways but the compression factor is too low and popcount should be done in binary, then the output reduced to ternary...
Here is a binary Popcount : neat and clean. Maybe a bit long/deep but effective, with significant bit/width reduction at each stage.

The "16" output wraps around to 1, as 16mod3=1. The rest of the conversion is a mess though.
But wait : the result will be mod3.
So we can already consider the weights 4, 8 and 16 pre-mod3 and go from there
- 4 mod 3 = 1
- 8 mod 3 = 2
- 16 mod 3 = 1
so then it's a matter of adding these weights on top of the weights 1 and 2.
The result is a bit weird but it works !

The final 3->2 conversion uses this table :
2 1 1 1 2 0 0 0 0 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 0 1 1 1 apparently not used
There are probably better ways to implement this function...
Yann Guidon / YGDES
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.