4. MCS与调制映射:从BPSK到1024-QAM,星座图映射与软解调LLR计算
各位同学,今天我们来聊聊WiFi6里一个非常核心的话题——MCS与调制映射。说实话,我刚入行那会儿,觉得调制不就是把比特扔到星座图上嘛,有啥难的?直到第一次调试接收机,发现解调出来的LLR全是错的,才意识到这里面的门道有多深。
MCS,全称是Modulation and Coding Scheme。WiFi6支持从MCS0到MCS11,一共12种速率。你想想看,从最简单的BPSK到最复杂的1024-QAM,这中间差了可不是一星半点。我习惯把MCS理解成「速率档位」,档位越高,每个符号携带的比特数就越多,但对信道质量的要求也越苛刻。
4.1 调制阶数与星座图
先看一张表,这是WiFi6支持的调制方式:
| MCS索引 | 调制方式 | 每符号比特数 | 编码率 |
|---|---|---|---|
| 0 | BPSK | 1 | 1/2 |
| 1 | QPSK | 2 | 1/2 |
| 2 | QPSK | 2 | 3/4 |
| 3 | 16-QAM | 4 | 1/2 |
| 4 | 16-QAM | 4 | 3/4 |
| 5 | 64-QAM | 6 | 2/3 |
| 6 | 64-QAM | 6 | 3/4 |
| 7 | 64-QAM | 6 | 5/6 |
| 8 | 256-QAM | 8 | 3/4 |
| 9 | 256-QAM | 8 | 5/6 |
| 10 | 1024-QAM | 10 | 3/4 |
| 11 | 1024-QAM | 10 | 5/6 |
嗯,这里要注意,MCS10和MCS11是WiFi6新增的。1024-QAM意味着每个符号要承载10个比特,星座图上有1024个点。密度相当高,对相位噪声和信道估计的要求也极高。
下面这张SVG图,我画了从BPSK到1024-QAM的星座图演化过程,你可以直观感受一下:
从图上你能看到,BPSK只有2个点,QPSK有4个,16-QAM有16个,64-QAM有64个。到了1024-QAM,我都没法一个个画点了,直接用个方框表示——32×32的网格,密密麻麻。
4.2 星座图映射规则
星座图映射,说白了就是把一串二进制比特,按照某种规则映射到复平面上的一个点。WiFi6用的是格雷编码,相邻星座点之间只有1个比特不同。这样做的好处是,如果噪声把符号判到了相邻点,只会错1个比特,而不是多个。
我举个例子,16-QAM的映射规则:
// 16-QAM 映射示例(格雷编码)
// 输入比特 b3 b2 b1 b0
// I路:b1 b0 -> 映射到同相分量
// Q路:b3 b2 -> 映射到正交分量
// 以I路为例,b1 b0 到幅度的映射:
// 00 -> -3
// 01 -> -1
// 10 -> +3
// 11 -> +1
// 完整映射表
b3 b2 b1 b0 | I分量 | Q分量
0 0 0 0 | -3 | -3
0 0 0 1 | -1 | -3
0 0 1 0 | +3 | -3
0 0 1 1 | +1 | -3
0 1 0 0 | -3 | -1
... | ... | ...
关键点:WiFi6的星座图映射,I路和Q路是独立映射的。这意味着你可以把二维问题拆成两个一维问题来处理。这在后面的软解调LLR计算中会非常有用。
4.3 软解调与LLR计算
好了,现在到了最核心的部分——软解调。为什么需要软解调?因为硬判决会丢失信息。你想想看,如果接收到的符号正好落在两个星座点的正中间,硬判决随便选一个,但软判决会告诉你「这个符号有60%的概率是0,40%的概率是1」。这个概率信息对后面的LDPC译码器来说,简直是救命稻草。
LLR,全称是Log-Likelihood Ratio,对数似然比。它的定义是:
LLR(b) = ln( P(b=1|r) / P(b=0|r) )
其中:
- r 是接收到的符号
- P(b=1|r) 是给定r时,比特b为1的后验概率
- P(b=0|r) 是给定r时,比特b为0的后验概率
LLR > 0 表示比特更可能为1
LLR < 0 表示比特更可能为0
|LLR| 越大,置信度越高
在实际工程中,我们不会直接算概率,太慢了。我习惯用最大对数近似(Max-Log-MAP)来简化计算。以16-QAM的I路为例,计算b1的LLR:
// 16-QAM I路 b1的LLR计算(Max-Log-MAP近似)
// 接收符号的I分量为 r_I
// 噪声方差为 sigma^2
// b1=1 对应的星座点集合:I ∈ {+1, +3}
// b1=0 对应的星座点集合:I ∈ {-1, -3}
LLR(b1) ≈ (1/sigma^2) * [ max_{I∈S1} ( -|r_I - I|^2 ) - max_{I∈S0} ( -|r_I - I|^2 ) ]
// 简化后:
// 如果 r_I > 0:
// LLR(b1) ≈ (2/sigma^2) * (r_I - 2)
// 如果 r_I < 0:
// LLR(b1) ≈ (2/sigma^2) * (r_I + 2)
我的经验:在实际芯片实现中,我们通常会把LLR量化成6比特或8比特的定点数。量化位宽的选择很关键——位宽太少会丢失软信息,位宽太多又浪费面积。我一般建议6比特起步,8比特更稳妥。曾经有个项目,为了省面积用了4比特量化,结果译码性能掉了0.5dB,最后不得不改版。
4.4 高阶调制的LLR计算技巧
到了256-QAM和1024-QAM,LLR计算就变得复杂了。每个符号要算8个或10个比特的LLR,如果每个比特都去遍历星座点,计算量会爆炸。
这里有个技巧——利用星座图的对称性。对于256-QAM,I路有16个电平,Q路也有16个电平。每个比特的LLR可以分段线性计算。我直接给出256-QAM I路比特的LLR计算公式:
// 256-QAM I路,归一化幅度为 ±1, ±3, ..., ±15
// 接收符号I分量为 r_I,噪声方差 sigma^2
// b0(最低位):决定符号的奇偶性
LLR(b0) = (2/sigma^2) * ( -|r_I| + 14 ) // 当 |r_I| > 14
LLR(b0) = (2/sigma^2) * ( -|r_I| + 12 ) // 当 12 < |r_I| ≤ 14
... // 分段处理
// b1:决定符号在象限内的位置
LLR(b1) = (2/sigma^2) * ( -||r_I| - 12| + 4 )
... // 类似处理
注意:1024-QAM的LLR计算更复杂,因为电平数增加到32个。我建议在硬件实现时,用查找表(LUT)来存储分段线性函数的系数。查找表的大小控制在256字节以内,对性能几乎没有影响。千万不要用CORDIC或者除法器,面积和延迟都受不了。
4.5 实际项目中的避坑指南
最后,分享几个我在项目中踩过的坑:
- 星座图归一化:不同调制阶数的星座图,平均功率不一样。BPSK的平均功率是1,但1024-QAM的平均功率是170.67。如果不做归一化,LLR计算中的sigma^2会完全乱掉。我习惯把所有星座图都归一化到平均功率为1。
- 相位噪声的影响:1024-QAM对相位噪声极其敏感。我曾经在测试中发现,接收机的相位噪声只要超过-35dBc@1MHz,1024-QAM的LLR就全是错的。后来加了相位跟踪环路才解决。
- AGC增益的补偿:接收信号经过AGC后,幅度会变化。LLR计算时一定要把AGC的增益补偿回去,否则sigma^2的估计会偏差很大。这个坑我至少见过三个团队掉进去过。
好了,关于MCS与调制映射,今天就讲到这里。记住,星座图映射是发射端的活,LLR计算是接收端的活。两者配合好了,你的WiFi6链路才能跑出漂亮的吞吐量。