Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • How to Use This Course
  • Reading Paths
  • Concept Map
  • How to Read the Diagrams
  • Part 0: What Is a Protocol?10
  • Part 1: Timing and Clocking11
  • Part 2: Encoding and Framing12
    • Line Codes
    • Framing Basics
    • Packet Anatomy
    • Bit Stuffing
    • DC Balance and Running Disparity
    • Block Codes
    • Scrambling
    • Alignment and Lock
    • Control Symbols and Ordered Sets
    • Flits, Phits and Packing
    • Protocols Compared: Encoding and Framing
    • Drills: Encoding and Framing
  • Part 3: Handshakes13
  • Part 4: Flow Control17
  • Part 5: Transactions19
  • Part 6: Concurrency and Performance17
  • Part 7: Ordering13
  • Part 8: Sharing and Arbitration12
  • Part 9: Deadlock and Liveness13
  • Part 10: Reliability and Recovery20
  • Part 11: Bring-Up and Link Management10
  • Part 12: Power8
  • Part 13: Shared State and Coherence9
  • Part 14: Security and Isolation7
  • Part 15: Specifying and Verifying11
  • Part 16: Protocols Dissected17
  • Part 17: Capstones5
  • Part 18: Interview Preparation6
Loading lesson

‹Part 2: Encoding and Framing
  1. Topics
  2. First Principles of Hardware Protocols
  3. Part 2: Encoding and Framing
  4. DC Balance and Running Disparity

Part 2 · Encoding and Framing · Working (W)

DC Balance and Running Disparity

Why AC-coupled links need as many ones as zeros, how running disparity measures the imbalance, and how codes keep it bounded.

On this page

    Note

    Level: Working (W) · Answers: Where does a message start and end?

    Before this: Line Codes

    A serial link has transitions everywhere, thanks to its encoding, and passes all its tests. Then a test sends a long block of data with many more 1s than 0s, all still with plenty of transitions. Errors appear, getting worse the longer the imbalance lasts, and the eye diagram shows the whole signal slowly sliding off centre.

    Why would the proportion of ones and zeros matter, when every bit has a clean transition?

    The obvious answer, and why it breaks

    The obvious answer is that only transitions matter: the receiver needs edges to recover its clock and levels to decide each bit, and the mix of values is the data's business. That is true for a DC-coupled link, where the wire carries the true voltage. Many fast links are AC-coupled: a capacitor in series blocks any steady voltage, so the two sides can sit at different DC levels. A capacitor passes changes but not averages, so the received signal's centre drifts towards the recent average of the data. If the data stays unbalanced for long, the centre slides, called baseline wander, and the receiver's threshold ends up too close to one of the levels.

    The idea: keep the running count of ones and zeros near zero

    Count +1 for every 1 sent and −1 for every 0. That running total is the running disparity. For an AC-coupled link to stay centred, it must stay within a small bound, all the time, not just on average over a long run. A code is DC-balanced if it guarantees that bound whatever the data:

    Scheme

    How it controls disparity

    Bound

    Raw NRZ

    It does not

    None: grows with any imbalance in the data

    Manchester

    Every bit is one high half and one low half

    ±1 within a bit, 0 at every bit boundary

    8b/10b

    Each byte has two possible 10-bit codes with opposite imbalance; the encoder picks the one that pushes the running disparity back towards zero

    Small and fixed

    Scrambling

    Makes the data look random, so ones and zeros are about equal on average

    Statistical: grows slowly, with no hard bound

    An AC-coupled link blocks DC, so the receiver sees the data shifted by its recent average.

    Build it: measure the drift

    The model sends 10,000 bytes of 0xFF, the worst imbalance, three ways and records the largest running disparity seen: raw NRZ, NRZ after a scrambler, and Manchester.

    example.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    """Running disparity: ones minus zeros sent so far.
    
    An AC-coupled link cannot carry a lasting excess of ones or zeros, so the running
    disparity must stay small. Compare three ways of sending a long run of 0xFF bytes:
    raw NRZ, scrambled NRZ, and Manchester (two half-bit symbols per bit, always one of each).
    """
    
    
    def lfsr_bits(n, state=0x1):
        out = []
        for _ in range(n):                 # x^15 + x^14 + 1, a common scrambling polynomial
            bit = ((state >> 14) ^ (state >> 13)) & 1
            state = ((state << 1) | bit) & 0x7FFF
            out.append(bit)
        return out
    
    
    def max_abs_rd(symbols):
        rd, worst = 0, 0
        for s in symbols:
            rd += 1 if s else -1
            worst = max(worst, abs(rd))
        return worst
    
    
    N = 80_000                             # 10,000 bytes of 0xFF
    data = [1] * N
    scr = [d ^ p for d, p in zip(data, lfsr_bits(N))]
    manch = [s for d in data for s in ((0, 1) if d else (1, 0))]
    
    print(f"{'bits sent':>10} {'raw NRZ':>9} {'scrambled':>10} {'Manchester':>11}")
    for n in (1_000, 10_000, 80_000):
        r, s, m = max_abs_rd(data[:n]), max_abs_rd(scr[:n]), max_abs_rd(manch[: 2 * n])
        print(f"{n:10d} {r:9d} {s:10d} {m:11d}")
    assert max_abs_rd(data) == N and max_abs_rd(manch) == 1 and max_abs_rd(scr) < N // 100
    print("PASS: raw data drifts without limit, scrambled data drifts slowly, Manchester stays within 1")

    It prints:

    Diagram
     bits sent   raw NRZ  scrambled  Manchester
          1000      1000        177           1
         10000     10000        230           1
         80000     80000        237           1
    PASS: raw data drifts without limit, scrambled data drifts slowly, Manchester stays within 1

    Raw data drifts by one for every bit, without limit. Manchester never exceeds 1. The scrambled stream is the interesting case: its disparity is much smaller than the raw data's, but it is not bounded. It wanders like a random walk, growing roughly with the square root of the length. That is why links that rely on scrambling for balance size their AC coupling and receiver to tolerate a statistical amount of wander, while 8b/10b links get a hard guarantee in exchange for their 20% overhead.

    The design space

    Approach

    Balance guarantee

    Cost

    DC-couple the link

    Not needed

    Both ends must share a common voltage range; harder across boards and cables

    Manchester

    Hard, per bit

    Twice the bandwidth

    8b/10b and similar balanced block codes

    Hard, small bound

    20% overhead (for 8b/10b)

    Scrambling with a long-period sequence

    Statistical

    Almost none in bandwidth; the receiver must tolerate some wander

    How real protocols chose

    Protocol

    How it handles balance

    PCI Express Gen1–2

    8b/10b: running disparity selects between each byte's two code groups, keeping the line DC-balanced.

    PCI Express Gen3–5 and 64b/66b links

    Scrambled payloads with a 2-bit sync header: balance is statistical, which the much lower overhead pays for.

    What breaks

    A test pattern meant to stress a link happens to be the scrambler's own sequence XORed with a constant, so after scrambling it becomes a long, strongly unbalanced stream (illustrative). Such "killer patterns" exist for any scrambler: data equal to the scrambling sequence turns into constants on the wire. On a link that relies on scrambling alone for balance, such a pattern causes baseline wander and errors. Real designs defend against it with sync headers that always contain a transition, with receivers that tolerate wander, and with test patterns chosen to probe this case deliberately.

    Why this matters

    Senior lens. Balance is a contract between the code and the channel. A hard-bounded code lets the channel use small coupling capacitors and a simple receiver; a statistical one shifts the burden to the receiver's baseline-wander correction and to analysis of worst-case data. When reviewing a link, ask whether it is AC-coupled, what bound the code guarantees, and whether anyone has computed what the receiver tolerates. A link that only works on random data has not been verified.

    Interview

    Asked: "What breaks if a link is not DC-balanced?"

    Weak answer: The clock recovery fails.

    Strong answer: On an AC-coupled link, a series capacitor blocks the average level, so unbalanced data makes the received signal's centre drift towards the data's recent average: baseline wander. The receiver's decision threshold ends up close to one level and errors rise, even though transitions are fine. Codes bound the running disparity: Manchester per bit, 8b/10b by choosing between two code groups, while scrambling only keeps it small statistically.

    Follow-ups: (1) What is running disparity and how does 8b/10b use it? (2) Why is scrambling a weaker balance guarantee?

    Check yourself A DC-coupled link carries unbalanced data. Is that a problem?

    Not for balance: with no series capacitor, the receiver sees the true levels. Transitions for clock recovery may still be needed, but disparity does not shift the baseline.

    Check yourself In the model, why does the scrambled stream's disparity keep growing slowly instead of staying near zero?

    Scrambled bits behave like random coin flips, and the running sum of random ±1 steps wanders, typically growing with the square root of the number of bits. Nothing pushes it back.

    Check yourself How does an 8b/10b encoder keep running disparity bounded?

    Many bytes have two code groups, one with more 1s and one with more 0s (or balanced ones). The encoder picks whichever moves the running disparity back towards zero.

    Key takeaways

    • AC-coupled links block the average level, so unbalanced data causes baseline wander and errors even with clean transitions.

    • Running disparity (ones minus zeros so far) must stay bounded; Manchester and 8b/10b guarantee it, scrambling only makes it likely.

    • Verify balance with worst-case patterns, not random data.

    Keep going

    Next: Lesson 2.6, Block Codes. 8b/10b, 64b/66b and 128b/130b: what each guarantees and what its overhead costs in real bandwidth.

    Related topics

    • Part 2 overview: Encoding and Framing

    Previous

    30 / 234

    Next: Block Codes

    Up next

    Up nextBlock Codes

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Line Codes
    • Framing Basics
    • Packet Anatomy