Codes used in CDMA

IS-95 uses three families of sequences at once: a long code for scrambling, a short code for cell identity and quadrature spreading, and a set of Walsh–Hadamard codes for the forward channels under one base station.

IS-95 Architecture
IS-95 forward-link architecture

Long code

The long code is an m-sequence from a 42-stage LFSR, clocked at the chip rate 1.2288 Mc/s. Its period is \(2^{42}-1\) chips, about 41 days at that rate. A per-call long-code mask, built from the A-key and the electronic serial number, selects a phase of that sequence. The masked long code both scrambles the traffic and completes the spreading.

Short code

The short code is an m-sequence of length \(2^{15}-1 = 32767\), from a 15-stage LFSR. It repeats roughly 75 times in two seconds. Each sector is assigned a distinct PN offset of the same sequence, which is how a handset finds and identifies a cell during acquisition. In the forward link the same family supplies a pair of short codes for the I and Q arms.

Walsh–Hadamard codes

Under one sector, IS-95 assigns 64 Walsh codes of length 64. cdma2000 extends that to 256. The codes are the rows of a Hadamard matrix. Written in \(\{0,1\}\) they become orthogonal once the alphabet is mapped to \(\pm 1\): the periodic cross-correlation of any two distinct rows is then exactly zero. Autocorrelation of a Walsh row is poor away from lag zero, so the network has to keep the forward link synchronous; that is why the short-code timing is established first.

\[H_1 = \begin{bmatrix} 0 & 0 \\ 0 & 1 \end{bmatrix}, \qquad H_{2N} = \begin{bmatrix} H_N & H_N \\ H_N & \overline{H}_N \end{bmatrix}\]

Each doubling of the matrix doubles both the number of codes and the code length. \(H_{64}\) therefore holds the 64 length-64 Walsh codes of IS-95. Conventionally Walsh 0 is the pilot, Walsh 32 is the sync channel, a few low-index codes are paging channels, and the remaining codes are traffic.

A short Python check that the mapped rows are orthogonal:

import numpy as np

def hadamard(n):
    """Sylvester construction over {0, 1}, n a power of two."""
    H = np.array([[0, 0], [0, 1]], dtype=int)
    while H.shape[0] < n:
        H = np.block([[H, H], [H, 1 - H]])
    return H

H = hadamard(8)
pm = 1 - 2 * H
G = pm @ pm.T
print(G)
print("off-diagonal max", np.max(np.abs(G - 8 * np.eye(8))))

See also

[1] Walsh Hadamard Code – Matlab Simulation
[2] Spread Spectrum Communications – Intro

Leave a Comment