Close
0%
0%

miniMAC - Not an Ethernet Transceiver

custom(izable) circuit for sending some megabytes over differential pairs.

Similar projects worth following
This is not Ethernet, though (initially) quite inspired by Fast Ethernet (100Base-TX) and using the same medium (RJ45/CAT5 or better) and magnetics. Or just plain matched impedance diffpair, I will not judge.

It should provide mostly equivalent performance but does not require all the IEEE 802.3xyz hoop-jumping: it could be implemented in a cheap FPGA (Ice45 ? A3P250?), TinyTapeout or even a Pi pico or something.

As it progresses, it looks more like a poor man's Fibre Channel over Cat5 with strong error detection and low latency.

Applications are wherever you need to deport devices, dozen of meters away with standard cabling (or circuit traces), such as sensors, sound, pictures... at a few megabytes per second or more (when RS485 wont cut it and you require electrical isolation).

The project evolves towards a MAC+PHY+AFE triad, no autoMDI, with minimal analog magic and some digital trickery. Actual line trilevel coding is not yet definitive, so nibble size will likely chang

20260326: #YGMII spin off

20260225: ASIC with Tiny Tapeout

20251113: Architecture update

20250525: spinning #miniPHY off.

.

miniMAC is an extension and application of #PEAC Pisano with End-Around Carry algorithm because the PEAC algorithm replaces the checksum, the scrambler and the 4b/5b table usually employed by 100Base-TX, see

166. Line encoding with PEAC : OK
167. Line encoding with PEAC: it's alive
168. PEACLS error detection (and correction?)
169. TODO: scan

Application is for embedded/custom data transfers over RJ45/Cat5 UTP/STP where the whole TCP/IP stack is not required and a simple FPGA/microcontroller are more than enough.

.

A PAM3-based + gPEAC18 version is currently in development. The GrayPar layer is replaced by a NRZI+Hammer convolutional error amplifier that detects more errors, faster, optimising the descrambler's work and reducing the FIFOs' depths. There is no error correction but detection is solid and fast, allowing almost immediate retransmit of the most recent data, thus optimising actual bandwidth in difficult environments (like industrial, automotive...).

 
-o-O-0-O-o-
 

Logs:
1. Let's start.
2. Tinkering with CircuitJS
3. AGC
4. Serial vs Parallel
5. Sender-side droop/wander prevention with MLT-3
6. Double parity
7. Flipping
8. a Quasi-Popcount
9. gPEAC again
10. Popcount
11. the bi-flipper topology
12. Ternary encoding
13. The whole flip+parity extension stage
14. Should 4 be flipped...
15. Popcount (better)
16. Run Length Limitation, reduced
17. Making it work
18. Protect the flip bits
19. Error detection
20. Modulation, simplified for now - NRZi
21. Architecture
22. Ternarity and more
23. SU(3)
24. mod3
25. mod3bis
26. Bidir PEAC+ParPop
27. Two lanes
28. Bidir ParPop : OK
29. Protocol
30. DPLL-1
31. I need a name.
32. Reversible PEAC scrambler
33. TMDS
34. PEAC treillis
35. PEAC Reversibility achieved
36. Bidirectional pipeline
37. Dual-lane version: easy
38. DPLL-2
39. Line compensations
40. Maximum avalanche time
41. Transition minimisation
42. The "same" symbol
43. PAM3 and the bi-Trits
44. The ParRot
45. Constellation 2
46. The spreader
47. Gray parity
48. One more bit...
49. Larger words
50. The new parity circuit
51. Permutations
52. Permutations 2
53. The last parity
54. Control Word Sequence
55. Rebuild
56. Detection latency and buffer depth
57. Burst errors
58. Protocol revision
59. MAC & PHYs
60. The error model of PEAC scramblers
61. Shared PEAC
62. Sub-protocol: QSDE
63. miniPHY
64. New pipeline
65. GrayPar17
66. ADD3-EAC
67. Move the NOTs
68. Fewer burst errors
69. spurious errors
70. Stats with GrayPar17 and PEAC16x2
71. Not XOR, not ADD, then what ?
72. Add, Sub and errors
73. Multi-bit errors
74. Galois fields ?
75. Better markers
76. Better stats
77. buffer prefix
78. gPEAC18
79. A matter of channels...
80. Architecture (summer edition)
81. Unit swap
82. Unit swap (2)
83. Extended control words
84. GrayPar18
85. Article
86. A variable-strength adaptive parity
87. New pipeline
88. New pipeline (2)
89. GrayPar18: 5+5+5+3
90. ParGray: it's reversible!
91. New modulo.
92. Nested Gray Parity Loops
93. New new modulo.
94. Error detection: how it fits in the protocol
95. Meanwhile: Koopman
96. Modular adder
97. Coding space
98. Architecture update
99. Parallel bus
100. C/D in the middle
101. gPEAC: the circuit
102. gPEAC circuit correction
103. New new new modulo.
104. Orbit length invariance
105. gPEAC: the (other) circuuit
106. gPEAC18 descrambler (la suite)
107. Bus Inversion
108. Error correction
109. Scrambler (clearer)
110. Scrambler and descrambler: almost ready
111. Scrambler and descrambler: VHDL
112. gPEAC stress test
113. More gPEAC18 results
114. Even more gPEAC18 results
115. PEAC flaw
116. NRZ FTW
117. Checking more assumptions
118. Max Hamming
119. A reversible mixing primitive
120. Hamming distance maximiser
121. MaxHam gen2
122. Brute-forcing the permutations
123. Brute-forcing in C
124. Proof, pudding.
125. Lemon and lemonade
126. Hammer = Hamming Maximiser
127. Looping the Hammer
128. Success
129. No more gPEAC ?
130. Gaming the error detection
131. Article + on hold
132....

Read more »

rb3.tgz

ReBirth3: the full gPEAC18 in C and VHDL

x-compressed-tar - 45.91 kB - 04/11/2026 at 19:03

Download

Hammer18_RTL.tgz

x-compressed-tar - 2.94 kB - 03/23/2026 at 14:51

Download

Hammer18.vhdl

updated/fixed netlist

x-vhdl - 3.83 kB - 03/07/2026 at 16:24

Download

miniMAC_2026_20251230.tbz

gPEAC + Hammer18 working together

x-bzip-compressed-tar - 193.25 kB - 12/30/2025 at 17:08

Download

Hammer18.tbz

implements the error maximiser

x-bzip-compressed-tar - 69.42 kB - 12/29/2025 at 00:32

Download

View all 34 files

  • Re-birth (3) : the Y/B paths

    Yann Guidon / YGDES04/09/2026 at 20:11 0 comments

    It's time to restore the Y path. For the encoder, it's mostly a copy-paste-rename of the X path, then the results are interconnected.

    (and seeing this, knowing what I now know, I realise it could become a mean TurboCode system if the Y output is interleaved with the X output)

    Copy-paste is easy, just as it is easy to mess up. Beware of the excess of confidence.

    Just as with the encoder, the B path is a copy-paste of the Y path, but the source is not the decoded output, rather it's a delayed version of the input.

    The A register has no feedback, it's just a temporal fence, and the T register is simply a delay (that gets initialised with INIT_X)

    ............................

    The copy-paste-rename took longer than it should, as usual, but the result matched the theory immediately. The encoder shows its duplication:

    // Scrambler
    int Message_in, OpM, OpY2, ResX, X, Y, CX,
        CXin, CXout, Scrambled_out, ResX2,
        OpX, OpY, CYin, CoutY, CoutY2, ResY, ResY2, CY;
    
    void init_scrambler() {
      X=INIT_X;
      Y=INIT_Y;
      CX=0;
      CY=0;
    }
    
    void cycle_scrambler() {
      OpM = Message_in;
      OpY2 = Y;
      CXin = CX;
      ResX = OpM + OpY2 + CXin;
    
      OpX = X;
      OpY = Y;
      CYin = CY;
      ResY = OpX + OpY + CYin;
    
      X = ResX & MASK18;
      ResX2 = ResX + ADJUST;
      CX = (ResX | ResX2) >> 18;
      if (CX)
        X = ResX2 & MASK18;
    
      Y = ResY & MASK18;
      ResY2 = ResY + ADJUST;
      CY = (ResY | ResY2) >> 18;
      if (CY)
        Y = ResY2 & MASK18;
    
      Scrambled_out = X;
    }

    The decoder is a copy-paste-rename of the B path and the asymetry is obvious:

    // Decrambler
    int Scrambled_in, OpM2, OpB2, B, A, ResA, CA,
        CAin, CAout, Message_out, error, ResA2,
        T, OpT, CBin, OpB, ResB, ResB2, CoutB, CoutB2, CB;
    
    void init_descrambler() {
      A=-1;
      B=INIT_Y;
      T=INIT_X;
      CA=1;
      CB=0;
    }
    
    void cycle_descrambler() {
      OpM2 = Scrambled_in;
      OpB2 = (~B)&MASK18;
      CAin = CA;
      ResA = OpM2 + CAin + OpB2;
    
      OpB = B;
      OpT = T;
      CBin = CB;
      ResB = OpB + OpT + CBin;
      T = Scrambled_in;
    
      A  = ResA & MASK18;
      ResA2 = A + MODULUS;
      CA = (ResA >> 18) & 1;
      if (!CA)
        A = ResA2 & MASK18;
    
      B = ResB & MASK18;
      ResB2 = ResB + ADJUST;
      CB = (ResB | ResB2) >> 18;
      if (CB)
        B = ResB2 & MASK18;
    
      Message_out = A & MASK17;
      error = (A >> 17 ) & 1;
    }

    ..................

    VHDL passes without effort but the tests don't match the C vectors. The INIT_X and INIT_Y are different so I have redefined them

    #define INIT_X  (187319) // "101101101110110111"
    #define INIT_Y  (111981) // "011011010101101101"
    ...
    generic (
      INIT_X : std_ulogic_vector(17 downto 0) := "101101101110110111"; -- 187319
      INIT_Y : std_ulogic_vector(17 downto 0) := "011011010101101101"; -- 111981
      ADJUST : std_ulogic_vector(17 downto 0) := "000000111110111110"; -- 4030
      MODULO : std_ulogic_vector(17 downto 0) := "111111000001000010"  -- 258114
    );

    And now the vectors are good ! 

    [   1234,  113215],
    [  38650,   79836],
    [  76066,  230468],
    [ 113482,   89606],
    [  19826,  226419],
    [  57242,   95327],
    [  94658,  101049],
    [   1002,  102721],
    [  38418,  241186],
    [  75834,  123209],
    [ 113250,  143698],
    [  19594,  173252],
    [  57010,   96252],
    [  94426,   48807],
    [    770,   51404],
    [  38186,  137627],
    [  75602,  226447],
    [ 113018,  143376],
    [  19362,   18054],
    [  56778,  198847],
    [  94194,  254317],
    [    538,  101394],
    [  37954,  135014],
    [  75370,   15711],
    [ 112786,  188142],
    [  19130,  110197],
    [  56546,   77641],
    [  93962,  225255],
    [    306,  209240],
    [  37722,  213797],
    [  75138,  202340],
    [ 112554,  195440],
    [  18898,   46011],
    [  56314,   20754],
    [  93730,  104182],
    [     74,   31280],
    [  37490,  172878],
    [  74906,  241574],
    [ 112322,  193754],
    [  18666,   83559],
    [  56082,   56616],
    [  93498,  177592],
    [ 130914,   13510],
    [  37258,   97447],
    [  74674,  148373],
    [ 112090,   25122],
    [  18434,   79840],
    [  55850,  142378],
    [  93266,    1520],
    [ 130682,  181315],
    [  37026,   89179],
    [  74442,   49796],
    [ 111858,  176392],
    [  18202,  132532],
    [  55618,   88226],
    [  93034,      61],
    [ 130450,  125704],
    [  36794,   32109],
    [  74210,  195229],
    [ 111626,    6640],
    [  17970,  108214],
    [  55386,  152270],
    [  92802,   39786],
    [ 130218,  229473],
    [  36562,  175603],
    [  73978,  184378],
    [ 111394,  139284],
    [  17738,  230007],
    ...
    Read more »

  • Re-birth (2.2) : modulo code

    Yann Guidon / YGDES04/08/2026 at 19:11 0 comments

    The architecture is settled and "just needs to be coded".

    The C code is pretty simple, one variable and 3 lines are added per peer (ResX2 & ResA2).

    // Decrambler
    int Message_in, OpM, OpY2, ResX, X, Y, CX, CXin,
       CXout, Scrambled_out, ResX2;
    
    void cycle_scrambler() {
      OpM = Message_in;
      OpY2 = Y;
      CXin = CX;
      ResX = OpM + OpY2 + CXin;
      X = ResX & MASK18;
      ResX2 = ResX + ADJUST;
      CX = (ResX | ResX2) >> 18;
      if (CX)
        X = ResX2 & MASK18;
      Scrambled_out = X;
    }
    
    
    // Decrambler
    int Scrambled_in, OpM2, OpB2, B, A, ResA, CA, CAin,
        CAout, Message_out, error, ResA2;
    
    void cycle_descrambler() {
      OpM2 = Scrambled_in;
      OpB2 = (~B) & MASK18;
      CAin = CA;
      ResA = OpM2 + OpB2 + CAin;
      A  = ResA & MASK18;
      ResA2 = ResA + ADJUST;
      CA = (ResA | ResA2) >> 18;
      if (CA)
        A = ResA2 & MASK18;
      Message_out = A & MASK17;
      error = (A >> 17 ) & 1;
    }
    

    Aaaand it doesn't work.

    As usual the encoder is fine but the decoder is a hot jacuzzi of "what's going on ?"

    It took a while (again) but this version finally works:

    void cycle_descrambler() {
      OpM2 = Scrambled_in;
      OpB2 = (~B)&MASK19;        /// <=== !!!
      CAin = CA^1;               /// <=== !!!
      ResA = OpM2 + OpB2 + CAin;
      A  = ResA & MASK18;
      ResA2 = A + MODULUS;       /// <=== !!!
      CA = ((ResA >> 18) &1);    /// <=== !!!!!!!!
      if (CA)
        A = ResA2 & MASK18;
      Message_out = A & MASK17;
      error = (A >> 17 ) & 1;
    }
    

    It's still quite unconventional and hard to grasp so a diagram is required. 

    The key detail is that the descrambler is not a modular addition, unlike the scrambler. Logically it's a modular subtraction and this changes a lot of non-obvious details. In particular:

    • the scrambler works in the unsigned, positive range, from 0 to 2×mod, hence the OR to detect overflow,
    • the descrambler, starting from range 0 to mod, subtracts another value from 0 to mod, so the output range goes from -mod to +mod, hence the sign bit is the MSB from the first "inverted addition" and no OR this time.

    The C code generates a longer list of test vectors, such that the thin slice of invalid values (from modulo to 262144) get corrected:

    [   1234,  225196],
    [  38650,    4498],
    [  76066,   41915],
    [ 113482,   79331],
    [  19826,  243789],
    [  57242,   23090],
    [  94658,   60507],
    [   1002,  224965],
    [  38418,    4266],
    [  75834,   41683],
    [ 113250,   79099],
    [  19594,  243557],
    [  57010,   22858],
    [  94426,   60275],
    [    770,  224733],
    [  38186,    4034],
    [  75602,   41451],
    [ 113018,   78867],
    [  19362,  243325],
    [  56778,   22626],
    [  94194,   60043],
    [    538,  224501],
    [  37954,    3802],
    [  75370,   41219],
    [ 112786,   78635],
    [  19130,  243093],
    [  56546,   22394],
    [  93962,   59811],
    [    306,  224269],
    [  37722,    3570],
    [  75138,   40987],
    [ 112554,   78403],
    [  18898,  242861],
    [  56314,   22162],
    [  93730,   59579],
    [     74,  224037],
    [  37490,    3338],
    [  74906,   40755],
    [ 112322,   78171],
    [  18666,  242629],
    [  56082,   21930],
    [  93498,   59347],
    [ 130914,   96763],
    [  37258,    3107],
    [  74674,   40523],
    [ 112090,   77939],
    [  18434,  242397],
    [  55850,   21698],
    [  93266,   59115],
    [ 130682,   96531],
    [  37026,    2875],
    [  74442,   40291],
    [ 111858,   77707],
    [  18202,  242165],
    [  55618,   21466],
    [  93034,   58883],
    [ 130450,   96299],
    [  36794,    2643],
    [  74210,   40059],
    [ 111626,   77475],
    [  17970,  241933],
    [  55386,   21234],
    [  92802,   58651],
    [ 130218,   96067],
    [  36562,    2411],
    [  73978,   39827],
    [ 111394,   77243],
    [  17738,  241701],
    [  55154,   21002],
    [  92570,   58419],
    [ 129986,   95835],
    [  36330,    2179],
    [  73746,   39595],
    [ 111162,   77011],
    [  17506,  241469],
    [  54922,   20770],
    [  92338,   58187],
    [ 129754,   95603],
    [  36098,    1947],
    [  73514,   39363],
    [ 110930,   76779],
    [  17274,  241237],
    [  54690,   20538],
    [  92106,   57955],
    [ 129522,   95371],
    [  35866,    1715],
    [  73282,   39131],
    [ 110698,   76547],
    [  17042,  241005],
    [  54458,   20306],
    [  91874,   57723],
    [ 129290,   95139],
    [  35634,    1483],
    [  73050,   38899],
    [ 110466,   76315],
    [  16810,  240773],
    [  54226,   20074],
    [  91642,   57491],
    [ 129058,   94907],
    [  35402,    1251]

    The VHDL code is almost a formality at this point, and it was pretty smooth this time. It still looks messy because of the use of signals instead of variables (to ease comparisons with gtkwave) but that's merely...

    Read more »

  • Re-birth (2.1) : constant-modulo adders

    Yann Guidon / YGDES04/08/2026 at 11:34 0 comments

    I didn't mean to reinvent the wheel but the recent experience with the tape-outs has taught me to reduce DFFs as much as possible. So as I return to the previous 2-cycle modular addition, which I thought was already reasonably efficient, and found that this circuit leads to mutual race conditions (which would explain the messy development several months ago), I understand that I must find a better approach.

    The last log 139. Re-birth (2) : the modulo. hints that there have been studies and Google led me to

    Hiasat, Ahmad. (2002). High-speed and reduced-area modular adder structures for RNS. Computers, IEEE Transactions on. 51. 84-89. 10.1109/12.980018. 

    https://www.researchgate.net/publication/3044437_High-speed_and_reduced-area_modular_adder_structures_for_RNS

    It starts there https://www.researchgate.net/figure/The-modular-adder-proposed-by-Bayoumi-and-Jullien-18_fig1_3044437 with a simple diagram from a different paper:

    Fig1 : The modular adder proposed by Bayoumi and Jullien [18].

    This inverts the order of the adders that I intended before but fair enough. There are 3 critical datapaths back-to-back:

    1. Adder A
    2. Adder B (though some overlap is possible since they both start from the LSB)
    3. the fanout for the MUX

    -------------------------------------------------------------------------------------------

    Fun fact: figure 2 of the paper describes a 2-cycle version ("Dugdale" topology), similar to the method I developed previously. The use of a latch (and not DFF) at this position is pretty smart but the size increase is still significant, adding 3 MUX.

    The Dugdale topology trades a constant adder for 3 MUX, 1 latch and 1 added cycles, which is not favourable when adders are relatively cheaper.

    -------------------------------------------------------------------------------------------

    More studies:

    Pipelined Two-Operand Modular Adders
    (Maciej CZYŻAK, Jacek HORISZNY, Robert SMYK) 2015 (13 years after Hiasat & Ahmad)

    https://www.radioeng.cz/fulltexts/2015/15_01_0148_0160.pdf

    -------------------------------------------------------------------------------------------

    The papers propose various enhancements, so the B&J circuit above, even though not optimal:

    • is a good starting point
    • would be somewhat optimised in our back by the synth tools
    • has less overall latency than a 2-cycle version (since the 2 carry chains can be close to each other and the LSB of Adder B can be evaluated soonder)
    • does not require over-registering like the 2-cycle version
    • promises ways to optimise later, when there is more time.

    The strategy now is to "isolate" the mod adder, such that it can be reworked after the first crude version proved it works. The adder is a bit larger than before but, considering the other factors, it's the fastest and most compact reasonable way to implement it in an ASIC, where the adder seems to be less of a concern than in an FPGA.

    And this leaves some potential optimisations on the table, for later.

    .

  • Re-birth (2) : the modulo.

    Yann Guidon / YGDES04/07/2026 at 00:28 0 comments

    The last log 138. Re-birth (1) has found 3 more coding flaws and there are probably even more.

    At this moment, I start to doubt the choice of the modulus, because being so close to 2^18 makes it pretty unlikely to overflow and create a carry (remember: the carry creates an additional avalanche). But then I forget that Y changes too (it's fixed for now) and I'll have to observe the activity of the carries. It will be interesting to compare the different values...

    The principle of the dual cycle is to pass the first sum into the adder again, but adding a constant (derived from the modulus) and see if the result overflows. If it does, the new (adjusted, wrapped-around) sum is written to the register, otherwise it is not modified.

    It's simple but not obvious because the whole thing mixes the numerical bases: the first phase is mod 262144 and the second phase is mod 258114, so there is an adjustment of 4030.

    Managing the carry bit is notoriously tricky in this situation and I have lost some hair already...

    ................................................

    Now something occurs to me. There could be a way out of this madness.

    First: I have noticed how ASIC have a different balance from FPGA. DFFs are 3x more costly than typical logic gates, which means that an adder is more economical than a whole pipeline regsiter.

    Second: It may be better to chain the adders, instead of cycling and sequencing and managing. This makes a slower clock but it does more in one period. Particularly if the 2nd add is a constant, which would use fewer gates.

    Third (and this is the stroke of genius that didn't occur to me until this morning): what if the constant add is moved upstream so it doesn't bother us? There would be a simpler pipeline and less complexity...

    Fourth: the pre-add would also work as error detection, because it does the work of the comparator.

    Except that the adjustment is conditional...

    Engineering really is the art of moving problems around.

    ................................................

    Back to the circuit. The RB1 does one thing: out = in + Y.

    In the RB2 (with modulo implemented) one way to know whether it has overflown is to check the carry bit, but there are 4030 cases out of 264144 (1 chance in 65, roughly, actually it's more complicated than that) that the sum is actually between the modulus and 2^18. The low chance makes me think again that the modulus is too high, but the 2nd turn is still necessary, if only because the result provides the corrected sum.

    Actually we want 2 things:

    • sum1 = in + Y
    • sum2 = in + Y + 4030

    Then we select the result according to the carry bit of sum2. This is a rather typical configuration that I have seen in previous works.

    ................................................

    I think I have uncovered a 5th flaw in the previous design, probably present in the VHDL "reference" as well: the A/X pipes are fed with B/Y but these values change with the phase, because they are not stabilised/registered => race condition
     
    No wonder I had such a bad time making it work !!!

    ................................................

    Now there are 2 ways to make the modulo adder work.

    • sum1 = in + Y
    • sum2 = sum1 + 4030

    (as I have seen somewhere and it looks good) or

    • sum1 = in + 4030
    • sum2 = sum1 + Y

    And I'd love to use this since this would reduce the effort on the Y/B pipelines that reuse the input. Pre-adjusting the input saves multiplexers (constant or classic) so in a way, this simplifies the system.

    This adds an adder in the pipeline but with two alternating constants (0 and 4030).

    However I recently found that a 2-cycles system needs more registers to prevent race conditions => A one-cycle solution would prevent this !

    Furthermore, it appears that factoring the adjustment into the input does not save much. There is still the need for the two bigger adders, and the added temporary registers bloat the system.

    ...................................................

    Read more »

  • Re-birth (1)

    Yann Guidon / YGDES03/31/2026 at 11:39 0 comments

    The last log 137. iHP26a - post mortem explains why and how the whole thing could be rebuilt almost from scratch, so let's now start with the basic integrator-differentiator pair. It's just a 18-bit version, the modulus is added later. Moreover, each step requires an identical/equivalent representation in C (JS), VHDL, Verilog and diagram.

    For the first step, we have a simple accumulator X, adding the (fixed) register Y to the incoming message. The decumulator does the reverse, subtracting B from the incoming message. It's not hard but keeping all representations in sync takes some efforts. (and yes, these are just registers, not accumulators, but I had to come up with a word...)

    And even this simple circuit is not totally obvious. The dataflow is easy and the encoder is simple but the carry requires a lot more thinking in the receiver.

    So how is the carry processed in the receiver ? what inversion is needed and where ?

    CA would be reset to 0.
    A subtraction needs the Cin to be set.
    But I remember that there is a double-inversion somewhere and some carry was no inverted.

    And I can't even get something as simple as above right on the first try in C, I must remove even more: the carry, the inversion...

    ................................................................

    But I finally managed to get something that works in C.

    #define MASK17  ((1<<17)-1)
    #define MASK18  ((1<<18)-1)
    #define MODULUS (258114)
    #define ADJUST  (262144-MODULUS)
    #define INIT_X   (56247) // "01101101110110111"
    #define INIT_Y  (2*(111981)) // "11011010101101101"  2× to trigger carry
    
    // Scrambler
    int Message_in, OpM, OpY2, ResX, X, Y,
        CX, CXin, CXout, Scrambled_out;
    
    void init_scrambler() {
      X=INIT_X;  // does not matter yet
      Y=INIT_Y;
      CX=0;
    }
    
    void cycle_scrambler() {
      OpM = Message_in;
      OpY2 = Y;
      CXin = CX;
      ResX = OpM + OpY2 + CXin;
      X = ResX & MASK18;
      CX = ResX >> 18;
      Scrambled_out = X;
    }
    
    // Decrambler
    int Scrambled_in, OpM2, OpB2, B, A, ResA,
        CA, CAin, CAout, Message_out, error;
    
    void init_descrambler() {
      A=-1;
      B=INIT_Y;
      CA=1;
    }
    
    void cycle_descrambler() {
      OpM2 = Scrambled_in;
      OpB2 = (~B) & MASK18;
      CAin = CA;
      ResA = OpM2 + OpB2 + CAin;
      A  = ResA & MASK18;
      CA = ResA >> 18;
      Message_out = ResA & MASK17;
      error = (ResA >> 17 ) & 1;
    }
    

    I modified INIT_Y to force the carry condition, don't worry.

    CA and CX are inverted from each other, but it comes from the computation, no need of explicit inverstion. Only initialise them properly: CX=0, CA=1. It's simple yet very not obvious...

    This inversion situation needs proper modelling and explanation.

    • CX and CA are complementary because the sum of INIT_Y and 1 + ~INIT_Y gives 1<<18.
    • CX goes 1 when Message_in >= (1 + ~INIT_Y)
    • conversely CA goes 1 when Scrambled_in >= INIT_Y (or something ... I'm still confused)
    • Both addends make the whole word go +(1<<18) so there IS a carry in any case, either in CA or CX.
    • In the end, CAout is fed directly into CAin. So we can remove the question marks.

    The code is in rb1.c, it generates these test vectors:

    [     42,  224004],
    [  24455,  248417],
    [  48868,   10686],
    [  73281,   35100],
    [  97694,   59513],
    [ 122107,   83926],
    [  15448,  239411],
    [  39861,    1679],
    [  64274,   26093],
    [  88687,   50506],
    [ 113100,   74919],
    [   6441,  230404],
    [  30854,  254816],
    [  55267,   17085],
    [  79680,   41499],
    [ 104093,   65912],
    [ 128506,   90325],
    [  21847,  245810],
    [  46260,    8078],
    [  70673,   32492],
    [  95086,   56905],
    [ 119499,   81318],
    [  12840,  236803],
    [  37253,  261215],
    [  61666,   23484],
    [  86079,   47898],
    [ 110492,   72311],
    [   3833,  227796],
    [  28246,  252208],
    [  52659,   14477],
    

     Now, the VHDL and mapped Verilog versions should be easy to deduce.

    .

    Well, VHDL certainly was (almost) a walk in the park. Encoding goes like this:

      -- encoder
      signal Message_in    : std_ulogic_vector(16 downto 0);
      signal Scrambled_out : std_ulogic_vector(17 downto 0);
      signal CX, CY : std_ulogic;
      signal  X,  Y : std_ulogic_vector(17 downto 0);
     signal OpM, OpY2: std_ulogic_vector(...
    Read more »

  • iHP26a - post mortem

    Yann Guidon / YGDES03/30/2026 at 17:14 0 comments

    The project https://github.com/YannGuidon/miniMAC_tx got tape-out-ed on ihp26a but the design is bork and could at best over-scramble noise...

    Then I tried my luck again with https://github.com/ygdes/miniMAC_5L on IHP 0p4 and at least the Hammer18 circuits work as intended, but the gPEAC18 resisted again and didn't make it.

    gPEAC is indeed a very delicate piece of circuit and the VHDL took ages to get right. I have the C reference code, the VHDL RTL but the Verilog structural gate-mapped version wouldn't work. Something somewhere is always working wrong, the debugging is excruciating (cumbersome and slowwww), Verilog is a PITA and the VHDL variables (in the RTL code) are not exposed to gtkwave, so it's impossible to compare with the Verilog version where all wires are visible signals.

    Today, the Verilog code for gPEAC is complete but fails to comply with the C and VHDL code. And I see no sane and reliable way to find what is wrong. So I'm forced to rebuild the WHOLE thing from scratch.

    The plan is to redesign everything simultaneously, starting from the simplest circuit and adding new circuits little by little, in four versions:

    • C reference
    • VHDL RTL
    • Schematic with precise annotations
    • Verilog gates

    To get from the current state to a smaller, easily testable circuit, both the encoder and decoder must be cut down:

    • The B pipeline must be cut from the A, the Y removed from X.
    • The pipelines get reduced to one cycle

    then it's rather easy to rebuild from scratch...

    Fortunately 135. Number comparison with the iHP PDK does not need to change.

    (update : well ok it did, a minor tweak)

  • Mapping the pipeline to iHP PDK

    Yann Guidon / YGDES03/21/2026 at 14:46 0 comments

    It's tempting to just plop the VHDL source code and let the synthesiser do the heavy lifting.

    But the pipeline is in Verilog and I use structural code only so I must map (actually synthesise) the circuits by hand.

    For this a clear view of the circuit is essential and circuitJS helps, but doing that also makes me reconsider several choices and the VHDL coding style must be deeply adapted.

    The last log has mapped the comparator, so that's one thing left on the list.

    The remaining circuits are inventoried.

    • The adder : I'll use dumb RTL style since I'm not yet operational with Jerem's Logilib. No time to dig further, it will work.
    • The DFF: there are three cases.
      • X and T are initialised with INIT_X, have feedback/enable
      • Y and B are initialised with INIT_Y, have feedback/enable
      • A is not initialised, has feedback/enable
      The case of A is already handled by modules.v:dffen_x18(), the others are a bit harder. I have found the solution in the PDK with sg13g2_sdfbbp_1 ! So here comes dffen_rs_x18() with independent SET_B and RESET_B pins. This way I can create the necessary registers.
    • There are muxes, to select the operands during each phase.
      • OPM is a basic mux2 done by mux2_x18() (for both sides)
      • OPX, OPY2 and OPT are muxed with a constant ADJUST.
      • OPB2 is muxed with the modulus and B is inverted.

      That's 2 circuits to create here, one just forces the constant, the other also inverts the operand. Here again the PDK does a great job. See the simulations

      So that's 2 modules to write using only these gates: ConstAdjOrPass() and ConstModOrNeg().

    And that's about it for the bulk of the datapath.

  • Number comparison with the iHP PDK

    Yann Guidon / YGDES03/21/2026 at 01:28 0 comments

    It didn't go as expected.

    The comparator doesn't use NAND/NOR because it actually makes it larger and/or bigger, and what matters is the critical path along the cascade. Fortunately A21OI is here and helps! the 4 gates are not in the critical datapath so over-optimising for speed is less interesting than optimising for area.

    Comparator circuit

    The tested source code is there : https://github.com/YannGuidon/miniMAC_tx/blob/main/src/gPEAC18.v

    /* This module compares a 18-bit number to the modulus.
       Compare a bitvector with the constant 258114 = 0x3F042 = 111111000001000010
       Any number equal or above raises X */
    module Compare_modulus(
        input wire [17:0] A,
        input wire En,
        output wire X
    );
      wire t1, t2, t3, t4, t5, t6, t7, _unused;
      assign _unused = A[0]; // The LSB has no effect.
      // first layer
      (* keep *) sg13g2_and4_1 L1a3_1(.X(t1), .A(A[17]), .B(A[16]), .C(A[15]), .D(En));
      (* keep *) sg13g2_and3_1 L1a3_2(.X(t2), .A(A[14]), .B(A[13]), .C(A[12]));
      (* keep *) sg13g2_or3_1  L1o3_1(.X(t3), .A(A[11]), .B(A[10]), .C(A[ 9]));
      (* keep *) sg13g2_or3_1  L1o3_2(.X(t4), .A(A[ 3]), .B(A[ 2]), .C(A[ 1]));
      // 2nd layer
      (* keep *) sg13g2_or3_1  L2o3_3(.X(t5), .A(t3),    .B(A[ 8]), .C(A[ 7]));
      (* keep *) sg13g2_or3_1  L2o3_4(.X(t6), .A(t4),    .B(A[ 5]), .C(A[ 4]));
      // 3rd layer
      (* keep *) sg13g2_a21o_2 L3ao_1(.X(t7), .A1(t6),   .A2(A[6]), .B1(t5));
      // Last stage
      (* keep *) sg13g2_and3_1 L4a3_3(.X( X), .A(t1),    .B(t2),    .C(t7));
    endmodule

    .

    I just realised I could do some bubble-pushing and shave a bit...

    The A21O can be turned into A21OI then feed to the AND3 turned into NOR3.

    The other AND3s are turned to NAND3s.

    The new circuit works

    .

  • Testing the Hammer

    Yann Guidon / YGDES03/10/2026 at 04:18 0 comments

    I have a first functional circuit in ASIC and I must write the Python code that tests the sea-of-xor.

    There are 19 key values to test: 0 and the 18 single-bit-at-1 configurations.

    Then throw a few "random" values for good measure, since the rest should be a linear combination of all the 18 single-bit cases, right ? And the all-ones case of course.

    But then the results of some test vectors could become vectors themselves. So some VHDL later and we get

    111111111111111111  101011111000110100  
    000000000000000000  000000000000000000  
    000000000000000001  110111011111011001  
    000000000000000010  110111011111011111  
    000000000000000100  110111101111011111  
    000000000000001000  110111101110011111  
    000000000000010000  010111100110110101  
    000000000000100000  110001101011001010  
    000000000001000000  000000011111111000  
    000000000010000000  101110111001000000  
    000000000100000000  111111000010100000  
    000000001000000000  111111011111111001  
    000000010000000000  111110111111111001  
    000000100000000000  111110111111110101  
    000001000000000000  001101111111010101  
    000010000000000000  000111100010110101  
    000100000000000000  110111000000100110  
    001000000000000000  111111000000101100  
    010000000000000000  100001001101110000  
    100000000000000000  000000011111111010  
    111111111000000000  011100010000010101  
    000000000111111111  110111101000100001  
    101010101010101010  100110111110100101  
    010101010101010101  001101000110010001  
    110111011111011001  011011011100100111  
    110001101011001010  000011011010101011  
    000000011111111010  110110111000100111  
    011011011100100111  101100110110001111  
    001101111111010101  111100010010000001  
    011011010110110101  011101101001011100  
    100100101001001010  110110010001101000  
    110110010001101000  101001010101001101  
    111100010010000001  001110001011100000  
    110110111000100111  101000101011111111  
    100110111110100101  101111000010110000  
    000011011010101011  100011000001110011  
    101000101011111111  110110010101011011  
    100011000001110011  101100010000011011  
    001110001011100000  101111110000110100  
    

    Now I must find again how Python encodes binary data.

    .....

    It seems to work.

    excepts that it outputs MSB first.

    I consider making a subcircuit just to implement and test the Hammer18 in 3 modes: direct, encode and decode

    ..

    result : it works well.

    and the current circuit uses only 22% of the tile.

    Routing stats

    Utilisation (%)Wire length (um)
    21.26517366

    Cell usage by Category

    CategoryCellsCount
    Filldecap fill1742
    ORxor2 or283
    Flip Flopsdfrbpq dfrbp sdfrbpq69
    Miscdlygate4sd367
    Bufferbuf66
    Multiplexermux236
    Inverterinv21
    Combo Logica22oi9
    NORnor44
    ANDand2 and42

    357 total cells (excluding fill and tap cells)

    The speed easily reaches 100MHz, can be pushed to 200MHz, 

    but the stats show that about half of the surface is DDFs, 1/4th is buffers/delays/fanouts, and 1/4 is logic gates...

    Cell type report:                     Count     Area
    Fill cell                              1742   20588.00
    Buffer                                    3      21.77
    Clock buffer                             23     493.52
    Timing Repair Buffer                    107    1701.91
    Inverter                                  9      48.99
    Clock inverter                           12      65.32
    Sequential cell                          69    3917.29
    Multi-Input combinational cell          146    2104.70
    Total                                  2111   28941.49

     now, that makes you think..

  • Fixed the Hammer's RTL

    Yann Guidon / YGDES03/07/2026 at 16:08 0 comments

    @alcim.dev  wanted to help me with the tapeout and translated Hammer18.vhdl to Hammer18.v with his custom AI tools. So I had to verify everything in detail. To my surprise, the AI did not hallucinate anything, but it uncovered two typos in the original file!

    Note: these typos did not affect the efficiency of the whole system, the change in error detection rate is insignificant, probably the same order of magnitude as using a different permutation, or swapping wires at the input or output. The correction was necessary for overall coherence reasons, and I expect other, better permutations will appear in the future so it was more important in December to move forward, with a "good enough" permutation and assess the overall system performance.

    So I have uploaded the new version of Hammer18.vhdl and, for reference, here is the online sim and here is the corresponding diagram:

    This was originally published in 124. Proof, pudding.

    The two typos explain the last glitch in 126. Hammer = Hamming Maximiser

    For more reference, the original permutations are

    Perm1965 =
      forward(  3  5  9 17 16 10 15 12  1  2  0 14  6  7 13  8 11  4 )
      reverse( 10  8  9  0 17  1 12 13 15  2  5 16  7 14 11  6  4  3 )
    Perm7515 =
      forward( 17  2 11  0  6 16  8  9 10 14  1  7 13 15  5 12  4  3 )
      reverse(  3 10  1 17 16 14  4 11  6  7  8  2 15 12  9 13  5  0 )
    Perm4021 =
      forward(  4 17  6  5  1 15  7 14 16 13  0  9 10  8 12  2  3 11 )
      reverse( 10  4 15 16  0  3  2  6 13 11 12 17 14  9  7  5  8  1 )
    

    but there was another glitch during the graphic transcription.

    And the above permutations were designed and meant to be fed into more structured code, such that copy-pasting the above numbers would indeed avoid any typo. But that transformation will be for later. 

    .............................................................................................................

    Another interesting realization is that the sea-of-xor, the latch and the combination-xor can work in different orders, allowing a better integration in the pipeline, where it amounts to only one XOR layer in the pipeline. Here are only a few possibilities:

    TODO:

    The new version of the file must be verified and the avalanche profile compared to the original diagram.

    ===> YES !

    ~/miniMAC$ ./runme_testHammer.sh
      total:200                                                 
     7   16   100001001101110000                                                 
     8   14   110111000000100110                                                 
     8    6   000000011111111000                                                 
     8    7   101110111001000000                                                 
     8    8   111111000010100000                                                 
     9   13   000111100010110101                                                 
     9   15   111111000000101100                                                 
     9   17   000000011111111010                                                 
     9    5   110001101011001010                                                 
    11    4   010111100110110101                                                 
    12   12   001101111111010101                                                 
    13    0   110111011111011001                                                 
    14    3   110111101110011111                                                 
    15   10   111110111111111001                                                 
    15    1   110111011111011111                                                 
    15   11   111110111111110101                                                 
    15    2   110111101111011111                                                 
    15    9   111111011111111001

    . .

    TODO:

    Solve the fanout imbalance issues

    .

    though so far, the Hammer circuit easily fits in the current 10ns cycle time.

    Update : still flies at 5ns cycle time. I'm so impressed!

View all 142 project logs

Enjoy this project?

Share

Discussions

Yann Guidon / YGDES wrote 12/25/2025 at 02:11 point

https://arstechnica.com/gadgets/2023/06/speed-matters-how-ethernet-went-from-3mbps-to-100gbps-and-beyond

  Are you sure? yes | no

Yann Guidon / YGDES wrote 11/23/2025 at 08:29 point

Toshiba was on the ParPop thing since at least 1983:

https://patents.google.com/patent/US4587445A/en

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/26/2025 at 02:56 point

https://connect.ed-diamond.com/gnu-linux-magazine/glmf-277/erreurs-en-rafales-multiparites-et-codes-gray-entrelaces

  Are you sure? yes | no

Yann Guidon / YGDES wrote 04/16/2025 at 14:03 point

"Not everybody can take that much fun. :-) "

  Are you sure? yes | no

Yann Guidon / YGDES wrote 04/16/2025 at 13:36 point

My approximate design parameters :

- Fclk = 100 to 130MHz (coming from "somewhere")
- 1 gate = 3 inputs max, approx 1ns (about 30% variation across voltage, process and temp variation)
- Input pins : some can do differential and dual-edge clocking, can be ganged to act as high speed comparators and create crude ADC. But their count must be kept low: 2 is nice, 3 is still OK, 4 has to be worth it.
- Output pins : can do differential and dual-edge clocking too

  Are you sure? yes | no

Yann Guidon / YGDES wrote 04/16/2025 at 05:08 point

https://www.academia.edu/5243141/A_CMOS_Transceiver_for_10_Mb_s_and_100_Mb_s_Ethernet

  Are you sure? yes | no

Yann Guidon / YGDES wrote 04/15/2025 at 11:07 point

Clock recovery can easily get incredibly complex...

https://en.wikibooks.org/wiki/Clock_and_Data_Recovery/Structures_and_types_of_CDRs/The_CDR_Phase_and_Frequency_Detector_PFD

But I can't use analog circuits here

  Are you sure? yes | no

Yann Guidon / YGDES wrote 03/26/2025 at 17:39 point

Some links from Tim for comparison :

https://ams-osram.com/de/innovation/technology/open-system-protocol

https://www.melexis.com/en/news/tech-talks/melibu

https://www.nxp.com/products/BMX6X02

https://www.analog.com/en/products/adbms6821.html

  Are you sure? yes | no

Yann Guidon / YGDES wrote 03/23/2025 at 19:30 point

20250323 !

So far we got :

- a pretty good 16-bit scrambler with a very long period, no risk of crash and parallel implementation : easier operation, lower power and

- the scrambled word has 2 additional marker bits for flagging the data vs control words, also providing a "sticky" checksum flag

- the parity/flip stage performs pop count on the 2 halves, extracting a parity flag that alters the data markers, and flips whole bytes when the number of set bits is lower than 4.

Result :

- 16 data bits are expanded to 20, which is the same +25% overhead as 100BaseT

- Far better and faster error detection, both from the scrambler and the parity/popcount levels.

- The maximum length of consecutive 0s is 10 by construction. This effectively bounds the bandwidth in a strict F-F/10 range, which is an important design parameter for the coupling transformers and the working frequency. This figure changes depending on the modulation scheme, as MLT3 divides the main frequency by 4.

- Droop management will use the popcounts from the parpop level, and insert "correction" packets when the drift exceeds a (configurable) value.

  Are you sure? yes | no

Yann Guidon / YGDES wrote 03/10/2025 at 00:35 point

https://www.iol.unh.edu/sites/default/files/testsuites/ethernet/CL25_PMD/PMD_Test_Suite_v3.5.pdf

"if more than 7 errors are observed in 3x10^11 bits (about 19,770,000 1,518-byte packets), it can be concluded that the error rate is greater than 10^-11 with less than a 5% chance of error. Note that if no errors are observed, it can be concluded that the BER is no more than 10-11 with less than a 5% chance of error."

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/29/2024 at 02:10 point

The seminal 64b/66b paper : http://www.omnisterra.com/walker/pdfs.talks/dallas.pdf

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/23/2024 at 18:03 point

at least it's something.
https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCBMB0CsCmBaMAGELqUig7LsAHGLAGwol4AsJUAzCLCJfQsmAFADuIJkl4ZHpTRhBKdgDcGg0Wl79Z6KEwp4U65Wi3QOAc2kjBsSgrHp2+kgQJRSPa1AdaLIAJwnbNd-0hPz3VBQbSDtUPk9-EAISH3DohVdIczAcCCtguJiocLRXaFdYdSLiorAkV3ANWiTxbnTs-hi0LH5xACchZocmhqVA9g6exR6WpUKXEe7hEFoUVsj4iIJXGhCaWqiViO8IjeWaMES3X3AjvazDpP3TmoHNg6Prtb71dgAlcDBaA48wL4OwDUlNNaNB6Fp0HAXH9vjM5p9YdUIe0EatQv84fNAsU7jCfgoMZcXiVcYSjnjdpUcQEUOEiYEbESNn94fSybcaQ5nhTnsz2eBsCIzlwBRpuRjeewACaVHBJSByyrhBXy8AAOVolGlSoUOAOuCSKVW6s1IsSjKOOyZ2tQiuwjNpPiCyjAGq1NLpep1N0iYQShsdUGdzIN4C9LN16xFEbDANZws5wVCQWCwejoftlS5aZlfqg01t8umhrd6btitQXMVIarAa5dhDdoLqB80z58L4IhbPpDyoLgclHp8yeV1fYogqVvJ6gtQIwRVojAgiHnKEBsGsxEorkStFoBWdJB0riIZGwOH3Cov5R4x9PtNwlBwwmsN4wO-YAGNRULDYLKTAkBIH8kKkCs3wkGA24kAUBAXpCODsMIECApQjLhtU6EHFEAA6ADOxD4cgsD4diRSkfkmpEAQswbo6KCuLQFEpOQerCN8zAXiEpElOg+HYDxJTFOA+HiMhApoVAFaYVJhq4QRJF4cRgnFMxeAUE0HG0FxilgGCJCwIQE5BJhWAqRoKD8ZZBFCcJYCidGfCMjITluFGAT-vSrnWqIhrfCIGEnEayhSvAABmACGACuAA2AAuiAxfAuZKNoa7jrw4D+bJWUnCqIXhdF8WJcl4CpZC6UdP8AU-M6wUiEUuLZflUHOvlDWvAEL45a1WHmB8vWxuA3V-HOTBoKC4KpVCHmSdy-6DlSs5LW5vozqtqE2FszLeS5c1OOwAD2URlWgwg7uAmCMPO65KFcMxHcNp3jRdekhBVa6kO9zRPbQj1LsCDEVDA13QMUrh6l913KIwf3HVgz3ncDcAfeoEMGbw0PykkcN0IjQMMKjDGQ5jd147jdKAxdINE+jUNk+EuOUADZ0E29oPgyT33KMzD20DYOAgAAYhAaCsBUsBg7ZQllIggvICAAAi8AxRFACe7D8yAgsi2V70siACsAJIALYAA7JRFAB2n7wJrjLCxA9BkWK0uGxAQttPAACOUXwDbGtax7EDQ4E7tK1FcVq-hADCaufkl9tlbrSSINgQbh4rMf4QA8mFYV4fAcVJ8H5WMArACyEUAB74QAaod8URbodtAA

  Are you sure? yes | no

Ken Yap wrote 10/21/2024 at 22:04 point

Ethernet does not imply TCP/IP. IP is just one of the protocols that can be transported on Ethernet. Historically there were other protocol families such as Novell's IPX which could be carried simultaneously with IP. However IP is now the standard. They all use the now standardised Ethernet frame which is the data link layer.

Your project establishes a different data link layer so cannot be used with standard Ethernet hardware except the cables and the sockets. But you knew that of course.

I've toyed with the idea of using Ethernet cables and sockets for carrying power and signals over up to a few metres purely as a local hack because I have lots of cables. Mainly to counter the proliferation of wall wart power supplies. I would have to ensure those sockets are never used with normal Ethernet connections.  PoE would be a standard way to get what I want with more flexibility but more hardware complexity. But truth be told, wall warts and WiFi or Bluetooth are probably preferable to Ethernet cables all over the place.

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/21/2024 at 22:23 point

Hi @Ken Yap !

I remember IPX, programming it in ASM around 1997... and the ISA Ethernet cards using coax, the T and terminators :-D

> But you knew that of course.

I do.

> purely as a local hack

Well, in some cases, I need to go beyond the local hack.

So far, I have implemented TCP/IP boards such as #WizYasep but they are too often overkill for the clients' needs. Hence this project, where I also explore alternative novel data processing techniques.

And in many of my applications, radio links can't be selected.

  Are you sure? yes | no

Ken Yap wrote 10/21/2024 at 22:54 point

Fortunately I have only myself to entertain these days. 🙂

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/22/2024 at 12:59 point

@Ken Yap 

and Hackaday helps you :-)

  Are you sure? yes | no

Ken Yap wrote 10/22/2024 at 13:13 point

There are other entertainments awaiting when I have exhausted/tire of this one. 😊

PS: Tagging the recipient is redundant when the reply is below theirs and just generates annoying email traffic.

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/22/2024 at 13:16 point

I didn't get a notification..

Let's see if it works this time.

  Are you sure? yes | no

Ken Yap wrote 10/22/2024 at 13:22 point

You certainly generated two emails to me with your first reply. 👿

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/21/2024 at 20:44 point

https://www.ti.com/lit/an/snla266a/snla266a.pdf

https://ww1.microchip.com/downloads/en/AppNotes/AN2686-Ethernet-Compliance-Test-10BASET-100BASETX-1000BASET.pdf

https://download.tek.com/document/61W_17381_3.pdf

https://cdn.teledynelecroy.com/files/appnotes/100base-t1-ethernet.pdf

https://pdfserv.maximintegrated.com/en/an/AN1738.pdf

https://bitsavers.org/components/national/_dataBooks/1995_National_Ethernet_Databook.pdf

https://ibis.org/summits/feb19/dmitriev-zdorov.pdf

 ...

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/21/2024 at 07:15 point

https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCBMB0CsCmBaMAGc0yRQDgCwGZZZJdsUUA2ATn3AHYRYQDGkwwAoAdxApPApoKuNGEEgUHAG7MqFAWljixaNJHD4UVcjvTzVEuBwDms+SuZkFEiRzFVwYfPMhLwKOutf7DOwuF8dXGo8EkhBYUg6WBRcEEQUaB1KFDBtKlg6XG1hXDA3BKSdQTStTOzKXDz-RKoqE0dnKE9Gl2xsG0lTCnaoNx6OyF7VBtQW73dx4dsediaJuZcWyVmncyp1djxwDZmQOq9+A531STA6CAGoI93IfjQqaAzkl50wJAdUNHxT7l5eu5xYRqe4cABOvBEUF6wOucVE5HBkNE4lhgJsdwaaJhUM08L2xwWKH4ExW7hJbjGXjcZNQ-DSmw8m12ZOODPJcXZkghdM5u15fR8XyRWz5mzA21JzDoOj+i0FjklNOkjGUqPp4jU7leomgQrgMroch+FCNpDk+iMAHsbBA0CI6oxfEwtd8ODb2AF7VoHDAXUlXBjHCB8O76F7mD6oHBAuQqHQKEpA1rziGwx07ZHHX7Y1oE0mXVAQB1QzaGJmHQ5EskE5AaFRcLB8Jh-cl44m+IX1AxQ-gM2gAGKZhCIBywIo6l7vRAMZAgAAi8AANgBDACeHD77hAQ4CgfYaDnAEkALYAB3gABMVwA7ADG8E3GZ3EFoX2SUEn8QgA7B8AAjgArvA94bludwvkW3zfguADCAA6ADOADyABmqGIfAAAuHBAA

  Are you sure? yes | no

Yann Guidon / YGDES wrote 10/21/2024 at 05:35 point

https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCBMB0CsCmBaMAGK0wA4DMrZgBYsA2SFTA48AdhFhAOzqTDACgB3OggqSX2MTSR+IFGwBuDTMNGwefXsPApVa1eGhUwWsWLhsA5tNm9KvEUrFswxAJzhbmKIMcoLrtCmhrs9CN7qdtTBYNTu4dTYKIQQiIExuHaYItRgkILEBJBRIIiYGLj4pHbYWek4SGT6dnZGjsTOOZANTZjOXvWNTa7dUO164sas7i7aqBYDnVysjWOtUNQt4jNO4HYt6bbry5wgtS2WKuSK1mEQfUcHp2h20Haw6k9qYEgOqGjYu1zXGdqqPSoKxAl1EWVM1gATiCCMIBuCbsc2NDBBCEUc0GBYF1Yf1nAjolZgR9ASpXM1rDMUOSlm4PEC9iTTngqGQOozqayTiMLKJxNCWVBuZzFsskQLINswBtwJLWZ4GOFVIy1n9Zds1eIAPZ6AIMFC1Oj6PVi7BsHXpcB6WGGmD0QL2qCykBmi3OPU2hx2-TUvSbZyukDu60Ghz2nyqaWwXAZP1Bl3mkC0D2hn1qaglbB2AjR9LhoIZwSx5S0M3Yd1oABieoQiDDEeez1eiFoyBAABF4AAbACGAE82OWVCBq1bYyM8hAAJIAWwADvAACY9gB2AGN4IPg6OmB91MdnpOR5D4ABHACu8HXA6AA only one transfo, then.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates