6  Bit rate, bandwidth and capacity

Open in Colab  Run this chapter’s code in Google Colab (no installation).

Slides 96–121. Dispersion stretches each bit. When neighbouring bits overlap too much, the receiver can no longer tell a “1” from a “0”: this is intersymbol interference (ISI). Noise and attenuation then decide how much overlap is tolerable. This chapter connects the fiber physics to the bit error rate.

6.1 Signals, spectra and limits (slides 97–105)

Nyquist: a noiseless channel of bandwidth \(B\) carries at most \(2B\) binary symbols per second (more with multi-level symbols). Shannon: with noise,

\[ C=B\log_2\left(1+\frac{S}{N}\right). \]

With the defaults you get the slide 104 example (31.9 kb/s on a 3.2 kHz line at 30 dB). For a single C-band channel (\(B\approx50\) GHz, \(S/N\approx20\) dB), Shannon allows about 330 Gb/s per polarisation. Commercial coherent transceivers now operate within a few dB of this limit.

Show the Python
rng = np.random.default_rng(0)
bits = fl.prbs(7, 24)
x = np.repeat(bits, 40).astype(float)
fig, axs = plt.subplots(3, 1, figsize=(8, 4.6), sharex=True)
for ax, snr in zip(axs, [1, 10, 100]):
    noise = rng.normal(0, np.sqrt(np.mean(x**2) / snr), x.size)
    ax.plot(x + noise, color=fl.PALETTE[0], lw=0.8); ax.plot(x, color=fl.INK, lw=1.2)
    ax.set_ylabel(f"S/N={snr}"); ax.set_yticks([])
axs[-1].set_xlabel("sample"); plt.tight_layout(); plt.show()
Figure 6.1: The same NRZ bit pattern received with S/N = 1, 10 and 100 (cf. slide 105).

6.2 Line codes: RZ and NRZ (slides 96, 120)

Show the Python
bits = np.array([0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0])
sps = 50
t = np.arange(len(bits) * sps) / sps
nrz = np.repeat(bits, sps)
rz = nrz * (np.tile(np.arange(sps), len(bits)) < sps // 2)
fig, axs = plt.subplots(2, 1, figsize=(8, 3.2), sharex=True)
axs[0].plot(t, rz, color=fl.PALETTE[1]); axs[0].set_ylabel("RZ")
axs[1].plot(t, nrz, color=fl.PALETTE[0]); axs[1].set_ylabel("NRZ")
for ax in axs:
    ax.set_yticks([0, 1]); ax.set_xticks(range(len(bits) + 1))
    for i, b in enumerate(bits): ax.text(i + .5, 1.15, str(b), ha="center", fontsize=8, color=fl.INK2)
    ax.set_ylim(-0.1, 1.35)
axs[1].set_xlabel("time (bit periods)"); plt.tight_layout(); plt.show()
Figure 6.2: The same bits in RZ and NRZ format. NRZ needs half the bandwidth for the same bit rate, while RZ is more robust to ISI and easier for clock recovery.

6.3 Dispersion-limited bit rate (slides 115–121)

For a Gaussian output pulse with rms width \(\sigma\) (\(\Delta\tau_{1/2}=2.355\sigma\), i.e. \(\sigma\approx0.425\Delta\tau_{1/2}\)), allowing the overlap shown on slide 116:

\[ B_\text{RZ}\approx\frac{0.25}{\sigma}=\frac{0.59}{\Delta\tau_{1/2}},\qquad B_\text{NRZ}\approx 2B_\text{RZ}\ (\text{slide 96}), \qquad f_\text{op}\approx0.75B,\quad f_\text{el}\approx0.70f_\text{op}. \]

Show the Python
D, dl, L = 8, 2, 10                  # ps/nm/km, nm, km
t12_per_km = D * dl                  # ps/km
BL = 0.59 / (t12_per_km * 1e-12)     # b/s·km
B = BL / L
print(f"Slide 121: Δτ½/L = {t12_per_km} ps/km → BL = {BL/1e9:.1f} Gb/s·km; "
      f"for 10 km B = {B/1e9:.2f} Gb/s, f_op = {0.75*B/1e9:.2f} GHz, f_el = {0.7*0.75*B/1e9:.2f} GHz")
Slide 121: Δτ½/L = 16 ps/km → BL = 36.9 Gb/s·km; for 10 km B = 3.69 Gb/s, f_op = 2.77 GHz, f_el = 1.94 GHz

6.3.1 Two regimes: source linewidth vs. signal bandwidth (new)

The rule \(\Delta\tau=|D|L\Delta\lambda\) assumes the source is broad (\(\Delta\lambda\) fixed by the laser). Modern DFB lasers are so narrow that the spectrum is set by the modulation itself, \(\Delta\lambda\approx\lambda^2B/c\). Then \(\Delta\tau\approx|D|L\lambda^2B/c\), and requiring \(\Delta\tau\lesssim1/B\) (one bit slot) gives the famous

\[ B^2L\lesssim\frac{c}{|D|\lambda^2}\quad\Rightarrow\quad\text{10 Gb/s: } \sim\!70\text{ km},\quad\text{40 Gb/s: } \sim\!5\text{ km at 17 ps/nm/km}. \]

Doubling the bit rate divides the reach by four.

Show the Python
Bs = np.logspace(9, 11.3, 100)
fig, ax = plt.subplots()
for k, dl in enumerate([1.0, 0.1]):
    ax.loglog(Bs / 1e9, 0.59 / (17e-12 * dl) / Bs * 2, "--", color=fl.PALETTE[k], label=f"source Δλ = {dl} nm (NRZ)")
ax.loglog(Bs / 1e9, c0 / (17 * PS * (1.55e-6) ** 2 * Bs**2) / 1e3, color=fl.INK, label="transform-limited, B²L rule")
ax.set_xlabel("bit rate (Gb/s)"); ax.set_ylabel("max. length (km)"); ax.legend(fontsize=8)
plt.show()
Figure 6.3: Dispersion-limited reach versus bit rate for standard SMF (17 ps/nm/km) at 1550 nm. Broad sources (dashed) give B·L = const. Narrow lasers give B²·L = const.

6.6 Going further with OptiCommPy

The notebook opticomm.ipynb uses OptiCommPy, a full research-grade library. Since version 0.10 the pulse-shaping API takes a parameters object, which is why some cells of the original notebook fail. The corrected minimal version below gives the same Q as our simulator.

Show the Python
from optic.models.devices import mzm, photodiode
from optic.models.channels import linearFiberChannel
from optic.comm.modulation import modulateGray
from optic.comm.metrics import bert
from optic.dsp.core import firFilter, pulseShape, upsample, pnorm
from optic.utils import parameters, dBm2W

SpS, Rs = 16, 10e9
pp = parameters(); pp.pulseType, pp.SpS = "nrz", SpS          # new API (>= 0.10)
pulse = pulseShape(pp); pulse /= abs(pulse).max()
pM = parameters(); pM.Vpi, pM.Vb = 2, -1
pC = parameters(); pC.alpha, pC.D, pC.Fc, pC.Fs = 0.2, 16, 193.1e12, SpS * Rs
pP = parameters(); pP.ideal, pP.B, pP.Fs, pP.seed = False, Rs, SpS * Rs, 1

np.random.seed(123); bitsTx = np.random.randint(2, size=20000)
sigTx = firFilter(pulse, upsample(pnorm(modulateGray(bitsTx, 2, "pam")), SpS))
for L in [0, 50, 100]:
    pC.L = L
    I = photodiode(linearFiberChannel(mzm(np.sqrt(dBm2W(3)), sigTx, pM), pC), pP)
    BER, Q = bert(I[0::SpS] / np.std(I), bitsTx)
    print(f"L = {L:3d} km: Q = {Q:5.2f}, BER = {BER:.1e}")
L =   0 km: Q = 17.98, BER = 0.0e+00
L =  50 km: Q = 10.94, BER = 0.0e+00
L = 100 km: Q =  3.61, BER = 1.0e-04

6.7 Try it yourself

  1. Add a chirp parameter to fl.imdd_link (\(E=\sqrt P\,e^{j\alpha_H\ln P/2}\), Henry factor \(\alpha_H\approx3\)–5) and show that the sign of \(D\) now matters.
  2. Replace the PIN with an APD (gain \(M\), excess noise \(F=M^x\)). Find the optimum gain at 100 km.
  3. Replace NRZ by PAM-4 (2 bits/symbol, 4 levels, used in 400G data-centre links). What do you gain in dispersion tolerance, and what do you lose in sensitivity?