物理层详解

本文详细解释 SparkLink SLE 物理层的设计与实现, 覆盖调制波形、帧结构、信道编码和收发流水线, 逐一对标 TXS-10002-2025 标准条款并说明代码中的实现方式。

调制方式

SLE 物理层支持两大类调制: 频移键控 (GFSK) 和相移键控 (PSK), 分别用于不同帧类型。

GFSK 调制 (§6.2.1.1)

高斯频移键控是 FT1 帧的唯一调制方式。标准规定:

  • 高斯滤波器带宽时间积 BT = 0.5

  • 调制系数 h 在 0.45 至 0.55 范围内, 默认 0.5

  • 比特 1 对应正频偏, 比特 0 对应负频偏

SLE 定义了 7 种带宽配置, 从 0.1 MHz 到 4 MHz:

带宽

符号周期

最小频偏

0.1 MHz

10 \(\mu\)s

23.125 kHz

0.25 MHz

4 \(\mu\)s

92.5 kHz

1.0 MHz

1 \(\mu\)s

185 kHz

2.0 MHz

0.5 \(\mu\)s

370 kHz

4.0 MHz

0.25 \(\mu\)s

740 kHz

代码实现: phy.gfsk.GFSKModulator 类。调制过程为 NRZ 映射 → 上采样 → 高斯滤波 → 频率积分 → 复基带:

\[ s(t) = \exp\!\left(j \cdot 2\pi h \int_0^t \sum_k a_k \cdot g(\tau - kT)\,d\tau\right) \]

解调采用非相干的频率鉴别器方案 (GFSKDemodulator), 通过相邻采样点的相位差提取瞬时频率。

PSK 调制 (§6.2.1.2)

FT2-FT4 帧使用相移键控, 支持三种调制阶数:

BPSK (每符号 1 bit):

  • 比特 0 → 相位 90°, 比特 1 → 相位 -90°

  • 偶数位符号额外顺时针旋转 90°

QPSK (每符号 2 bit):

  • 00→45°, 01→135°, 11→-135°, 10→-45°

  • 偶数位额外 -45° 旋转

8PSK (每符号 3 bit):

  • Gray 编码, 22.5° 间隔

  • 偶数位额外 -22.5° 旋转

"偶数位"的定义: 无线帧的第一个符号处于奇数位 (索引 0 = 奇), 索引 1 = 偶, 以此类推。这一额外旋转有助于改善时钟恢复性能。

脉冲成型使用平方根升余弦 (RRC) 滤波器, 滚降系数 \(\beta = 0.4\), 每符号采样数默认 4。收发两端各一个 RRC 滤波器, 级联后满足 Nyquist 无码间干扰准则。

代码实现: phy.psk.PSKModulator 类。星座映射定义在 BPSK_MAP, QPSK_MAP, _8PSK_MAP 等常量中。导频符号共用同一相位查找表, 由 phy.pilot 模块生成。

此外还有一种无旋转 BPSK 映射 (0→0°, 1→180°), 用于同步信号 3/4 中的 m 序列调制, 不参与偶数位旋转。

多音信号 (§6.2.1.3)

多音信号由 N 个单音叠加:

\[ S(t) = \sum_{i=0}^{N-1} A_i \cdot e^{j(\omega_i t + \phi_i)} \]

主要用于射频校准和测量场景。phy.multitone 模块实现了可配置音数、幅度和初始相位的多音信号生成。

UWB 脉冲 (§6.2.1.4)

超宽带脉冲信号采用 Kaiser 窗参考波形 (\(\beta = 10\)), 支持两种带宽:

信号带宽

脉冲宽度 \(T_p\)

窗口 \(T_w\)

\(\geq\) 500 MHz

2 ns

0.5 ns

\(>\) 1300 MHz

0.75 ns

0.2 ns

码片调制 \(c(n) \in \{-1, 0, +1\}\), 最大脉冲重复频率 499.2 MHz。

代码实现: phy.uwb_pulse 模块, 提供参考脉冲生成、码片调制和互相关验证。

帧结构 (§6.3)

无线帧的组成

每个物理帧由帧头和数据两部分构成:

┌─────────── 帧头 ───────────┐┌───── 数据 ──────┐
│ 前导码 │ 同步序列 │ 控制信息 │ 载荷数据 │ CRC   │
└───────┴─────────┴─────────┘└─────────┴───────┘

各帧类型的差异集中在帧头的编码和调制方式上:

FT1 — 广播帧 (§6.3.2)

  • 前导码: GFSK, [0,1] 交替, 10 \(\mu\)s

  • 同步序列: sync_signal_1, 32 位→32 个 GFSK 符号

  • 控制信息: A 组, 无 Polar 编码, GFSK 调制

  • 载荷: 不经 Polar 编码, 直接 GFSK 调制

  • 典型用途: 广播、发现、接入请求/响应

FT1 是最轻量的帧类型, 没有前向纠错编码开销。控制信息头部用 BCH 码保护, CRC 种子由同步序列低位确定。

FT2 — 短头数据帧 (§6.3.3)

  • 前导码: PSK, [\(\pi/4\), 0] 交替, 10 \(\mu\)s

  • 同步序列: sync_signal_2, 64 位→32 个 QPSK 符号

  • 控制信息: A 组, Polar(64,K) 编码→32 QPSK 符号, 导频间隔 16

  • 载荷: 码块分割 (无段内 CRC) → Polar 编码 → PSK 调制 + 导频

  • 导频: 可选, 间隔 4/8/16

FT3 — 长头数据帧 (§6.3.4)

  • 前导码: PSK, [\(\pi/4\), 0] 交替, 12 \(\mu\)s

  • 同步序列: sync_signal_3, 31+31 位→62 个 BPSK 符号 (基于 m31 序列)

  • 控制信息: B 组, Polar(256,K)→128 QPSK 符号, 导频间隔 4

  • 载荷: 码块分割 (含段内 CRC) → Polar 编码 → PSK 调制 + 导频

  • 特点: B 组 CRC 种子 = 0x555555 ^ LLID

FT4 — 扩展头数据帧 (§6.3.5)

  • 前导码: PSK, [\(\pi/4\), 0] 交替, 16 \(\mu\)s

  • 同步序列: sync_signal_4, 63+63 位→126 个 BPSK 符号 (基于 m63 序列)

  • 控制信息: B 组, Polar(256,K)→256 BPSK 符号, 导频间隔 4

  • 载荷: 与 FT3 相同的编码方案, 但同步序列更长, 适合低信噪比场景

时序参数

系统基础时隙 \(T_{sys} = 125\,\mu s\), 由 30 位计数器表示当前时刻。调度时隙有 25/50/75/100/125 \(\mu\)s 五种选择。帧的空口时长由以下公式决定:

\[ T_{frame} = T_{preamble} + T_{sync} + T_{ctrl} + T_{data} + T_{guard} \]

代码实现: phy.frame 模块的 _SYNC_CONFIG_CTRL_CONFIG 字典定义了四种帧类型的完整参数。assemble_frame_bits() 生成比特级帧结构, frame_to_symbols() 完成到调制符号的转换。

物理层控制信息 (§6.4)

控制信息是帧头中紧跟同步序列之后的结构化字段, 携带帧类型、载荷长度、MCS 等元信息。

A 组 (FT1/FT2)

A 组控制信息使用 CRC12 校验, 种子来自同步序列的低 12 位。定义了 7 种子类型:

类型

用途

A1

广播/发现/接入

A2

异步数据 (控制面)

A3

异步数据 (数据面)

A4

异步数据 (复用)

A5

同步等时

A6

半可靠组播反馈

A7

测量管理

B 组 (FT3/FT4)

B 组使用 CRC24B 校验, 种子固定为 0x555555, CRC 结果与链路标识 LLID 异或。定义了 5 种子类型 (B1-B5), 对应异步数据、同步等时和测量等场景。

代码实现: phy.control_info 模块提供 ControlInfoA1ControlInfoA7ControlInfoB1ControlInfoB5 等数据类, 各自实现 pack()unpack() 方法。

同步信号 (§6.2.3)

同步序列用于接收端定位帧起始位置。SLE 定义了 6 种同步信号:

信号

长度

调制

生成方式

帧类型

sync_signal_1

32 bit

GFSK

GoldCode(32)

FT1

sync_signal_2

64 bit

QPSK

GoldCode(64)

FT2

sync_signal_3

62 bit

BPSK

m31+m31, pid 控制

FT3

sync_signal_4

126 bit

BPSK

m63+m63, pid 控制

FT4

sync_signal_5

32 bit

GFSK

安全随机函数

FT1 (安全)

sync_signal_6

64 bit

BPSK

安全随机函数

FT2 (安全)

sync_signal_3/4 的两段 m 序列由 PID (24 位) 通过哈希选择初始状态, 使得不同链路的同步序列正交。sync_signal_5/6 使用密码学安全随机数生成, 防止被预测。

代码实现: phy.sync_sequence 模块实现全部 6 种信号的生成, common.m_sequence 提供底层 m 序列算法。

前导码 (§6.2.2)

前导码位于帧最前端, 用于接收端的载波同步和符号定时恢复:

帧类型

波形

持续时间

样式

FT1

GFSK

10 \(\mu\)s

[0,1,0,1...] 交替

FT2

PSK

10 \(\mu\)s

[\(\pi/4\), 0, \(\pi/4\), 0...] 交替

FT3

PSK

12 \(\mu\)s

同上

FT4

PSK

16 \(\mu\)s

同上

前导码长度随帧类型递增, FT4 最长 (16 \(\mu\)s), 提供更好的同步捕获性能。

代码实现: phy.preamble.generate_preamble() 函数根据帧类型自动选择波形和时长。

导频 (§6.7)

导频符号是已知相位的参考符号, 周期性插入数据符号流中, 用于接收端进行信道估计和相位跟踪。

导频相位与该调制阶数的标准相位一致: BPSK 90°, QPSK 45°, 8PSK 22.5°。偶数位导频执行与数据符号相同的额外旋转。

插入规则: 每 \(N\) 个数据符号后插入 1 个导频, \(N\) 可选 4/8/16。帧末尾的导频可省略。

FT1 不使用导频。FT2 导频可选 (默认间隔 16)。FT3/FT4 强制使用导频 (默认间隔 4)。

代码实现: phy.pilot.insert_pilots()remove_pilots() 函数。

信道编码 (§6.9-6.11)

CRC 校验 (§6.9)

SLE 使用四种 CRC:

类型

生成多项式

用途

CRC12

\(D^{12}+D^{11}+D^3+D^2+D+1\)

A 组控制信息

CRC24A

\(D^{24}+D^{23}+D^{18}+D^{17}+D^{14}+D^{11}+D^{10}+D^7+D^6+D^5+D^4+D^3+D+1\)

载荷段, B组

CRC24B

(同 24A 不同多项式)

码块分割段内 CRC

CRC32

标准 CRC-32

长载荷

CRC 计算支持种子值, A 组种子来自同步序列, B 组种子 = 0x555555 ^ LLID

代码实现: common.crc.crc_calculate(), 支持 Rust 加速 (_HAS_RUST_CRC 自动检测)。

Polar 编码 (§6.10.1)

SLE 的前向纠错采用 Polar 码, 核心参数:

  • 母码长度 \(N\): 32, 64, 128, 256, 512, 1024

  • 信息位数 \(K\): 由 MCS 索引和载荷长度决定

  • 可靠性序列: 标准附录 C 给出 1024 阶固定排序

编码器执行蝶形 GF(2) 变换, 解码器采用逐次消除 (SC) 算法, 辅以 SSC 剪枝 (rate-0/rate-1 子树快速路径)。

代码实现: common.polar.PolarEncoder / PolarDecoder, 均支持 Rust 加速 (PyO3 扩展 nearlink_sdr_accel)。编码加速约 10 倍, 解码加速约 10 倍。

码块分割 (§6.10.2)

当载荷超过单个 Polar 码块容量时, 进行码块分割:

  • 无段内 CRC (FT2): 载荷等分为多个码块, 每块独立 Polar 编码

  • 含段内 CRC (FT3/FT4): 每个码块附加额外 CRC, 增强可靠性

代码实现: common.code_block_seg 模块的 segment_without_crc()segment_with_crc() 函数。

BCH 编码 (§6.11)

FT1 控制信息头部使用 BCH 码保护:

  • BCH(31,26): 可纠正 1 位错误

  • BCH(63,24): 可纠正更多错误, 用于更长的控制字段

代码实现: common.bch 模块。

信道比特加扰 (§6.10.4)

加扰使用 7 位 Galois LFSR, 多项式 \(x^7 + x^4 + 1\), 周期 127。种子 (whitening_seed) 在控制信息中标明, 收发端使用相同种子即可还原。

代码实现: common.scrambler.scramble(), 内部预计算一个周期的加扰序列后用 tile 扩展。

MCS 表 (§6.10.5-6.10.6)

调制与编码方案 (MCS) 索引决定了一次传输的调制阶数和码率:

MCS

调制

每符号比特

码率

0

BPSK

1

1/4

1

BPSK

1

1/3

2

BPSK

1

1/2

3

BPSK

1

2/3

4

BPSK

1

3/4

5

QPSK

2

1/2

6

QPSK

2

2/3

7

QPSK

2

3/4

8

(无编码 FT1)

1

1

9

8PSK

3

1/2

10

8PSK

3

2/3

11

8PSK

3

3/4

MCS 8 用于 FT1 的不编码直通模式。速率匹配通过重复或打孔将 Polar 编码输出适配到目标资源数。

代码实现: common.mcs 模块定义了完整的 MCS 表和速率匹配参数。

跳频 (§6.10.3, §8.1)

SLE 窄带系统在 2402-2480 MHz 频段内使用 79 个信道 (1 MHz 步进)。跳频序列由伪随机数生成器驱动, 每个调度点切换一次信道。

关键参数:

  • 跳频种子: 24 位, 决定序列的随机性

  • 跳频地图: 79 位 bitmap, 标记每个信道的可用状态

  • 最少可用信道: 有下限门限, 防止可用信道过少

代码实现: phy.freq_hopping 模块的 FreqTable, 管理信道列表、跳频序列和屏蔽操作。

发射流水线 (§6.10)

完整的 TX 处理链路 (phy.tx_pipeline.tx_chain):

应用数据
  ↓
CRC 附加                   ← common.crc
  ↓
码块分割                    ← common.code_block_seg
  ↓ (FT2-4)
Polar 编码                  ← common.polar
  ↓
比特加扰                    ← common.scrambler
  ↓
符号映射                    ← phy.psk / phy.gfsk
  ↓ (FT2-4)
导频插入                    ← phy.pilot
  ↓
帧组装                      ← phy.frame
  (前导 + 同步 + 控制信息 + 载荷)
  ↓
脉冲成型                    ← RRC / GFSK 滤波
  ↓
复基带 IQ 信号输出

发射参数通过 TxConfig 配置, 包含帧类型、MCS 索引、PID、加扰种子、CRC 长度和导频间隔等。

接收流水线 (§6.10)

RX 处理链路 (phy.rx_pipeline.rx_chain) 是发射的逆操作:

复基带 IQ 信号输入
  ↓
匹配滤波                    ← RRC / GFSK 频率鉴别
  ↓
帧同步                      ← 同步序列互相关
  ↓
头部提取与解码
  符号解映射 → 解扰 → Polar 解码 → CRC 校验
  ↓
导频去除                    ← phy.pilot
  ↓
载荷解调与解码
  符号解映射 → 解扰 → Polar 解码 → 码块重组 → CRC 校验
  ↓
数据比特输出 + CRC 状态

帧同步通过滑动互相关检测同步序列的峰值位置, 超过门限则认为检测到帧。

测量帧 (§6.3.6-6.3.11)

SLE 定义了多种专用测量帧, 用于定位和感知:

类型

结构

用途

测量帧类型 1

前导+同步+均衡保护+切换间隔+测量信号

窄带测距

测量帧类型 2

仅测量信号

简化测量

测量帧类型 3

前导+同步+均衡保护

信道探测

测量帧类型 4

完整数据帧+测量信号

通信+测量混合

UWB 脉冲测量帧

UWB 脉冲序列

超宽带测距

代码实现: phy.measurement_frame, phy.measurement, phy.measurement_tx 模块。

射频合规 (§8)

phy.rf_compliance 模块实现了标准第 8 章的射频参数校验:

  • 发射机: 输出功率等级、GFSK 调制精度 (频偏容限)、PSK 调制精度 (EVM)、GFSK 杂散发射、PSK 频谱模板

  • 接收机: 灵敏度与最大输入电平、信道选择性、杂散发射、RSSI 测量精度

  • UWB: 信道参数合规、频谱掩模、归一化均方根误差

这些校验函数返回合规/不合规的判定, 可用于仿真结束后的自动验证。