前向纠错FEC
> 目标:用一份文档快速建立 FEC(Forward Error Correction,前向纠错)的完整认知:
> 1)常见算法有哪些、各自优劣;
> 2)一种典型算法的纠错原理;
> 3)在 FPGA 中如何落地实现;
> 4)给出核心伪代码,便于工程实现。
---
1. FEC 是什么,为什么重要
FEC 的核心思想:
• 发送端在原始数据中加入冗余校验信息;
• 接收端不依赖重传,仅根据冗余信息检测并纠正部分错误。
FEC 的工程价值:
• 降低误码率(BER)
• 提升链路有效吞吐(减少重传)
• 提升系统鲁棒性(弱信道、长距离、高速链路)
典型应用:
• 光通信(400G/800G 以太网)
• 无线通信(4G/5G)
• 存储与传输(SSD、卫星链路)
• 高速 SerDes / Chiplet 互连
---
2. 常见 FEC 算法家族与优劣
2.1 奇偶校验(Parity)
• 特点:最简单,硬件开销极低
• 能力:只能检测奇数个 bit 错误,通常不能纠错
• 场景:低成本错误检测
优点:
• 逻辑极简、时延极低
缺点:
• 纠错能力几乎没有
2.2 汉明码(Hamming)
• 特点:典型线性分组码
• 能力:常见 SEC/DED(单错纠正,双错检测)
• 场景:存储保护(ECC 内存等)
优点:
• 编解码复杂度低
• 适合中小规模硬件
缺点:
• 强噪声信道能力不足
2.3 BCH 码
• 特点:强大的代数分组码,可配置纠错能力 t
• 场景:NAND Flash、存储控制器
优点:
• 多比特纠错能力强
• 理论体系成熟
缺点:
• t 增大时解码复杂度和时延明显上升
2.4 Reed-Solomon(RS)码
• 特点:符号级纠错(按 GF(2^m) 符号)
• 场景:光盘、广播、部分通信系统
优点:
• 对突发错误(burst error)效果好
• 工程成熟度高
缺点:
• 高速超大吞吐场景中,硬件开销与功耗压力较大
2.5 卷积码 + Viterbi
• 特点:序列码,经典最大似然解码
• 场景:早期无线通信
优点:
• 理论和实现成熟
缺点:
• 码长与约束长度上升时复杂度快速增加
2.6 Turbo 码
• 特点:迭代译码,接近香农极限(历史上)
• 场景:3G/4G 某些链路
优点:
• 误码性能好
缺点:
• 迭代译码时延较高、并行化复杂
2.7 LDPC(Low-Density Parity-Check)码
• 特点:稀疏校验矩阵 + 迭代译码
• 场景:5G、Wi-Fi、高速以太网/光通信等
优点:
• 性能强,接近香农极限
• 适合高并行硬件实现
缺点:
• 译码架构复杂,存储带宽和消息调度要求高
2.8 Polar 码
• 特点:信道极化理论,5G 控制信道常见
• 优点:理论优雅,某些场景表现好
• 缺点:实现和优化策略依赖具体码长与列表译码参数
---
3. 如何选择 FEC(工程视角)
选择维度建议:
1. 目标 BER / FER
2. 吞吐目标(Gbps)
3. 允许时延(ns/us/ms)
4. 资源预算(LUT/BRAM/DSP)
5. 功耗预算
6. 标准约束(协议规定了哪种码)
经验规则:
• 存储类多见 BCH/LDPC(取决于介质误码特性)
• 高速通信链路主流是 LDPC / RS-FEC(视协议)
• 控制信道、短码场景可见 Polar/其他专用码
---
4. 典型算法深讲:LDPC
> 这里选择 LDPC 作为典型算法,因为它在现代高速通信和网络中非常主流,且 FPGA 实现价值高。
4.1 基本定义
LDPC 是一种线性分组码,满足:
• H:稀疏校验矩阵(M x N)
• c:码字
译码本质:
• 给定信道软信息(LLR),通过 Tanner 图上的迭代消息传递,逼近最可能码字。
4.2 Tanner 图视角
图中有两类节点:
• 变量节点(VN,Variable Node)
• 校验节点(CN,Check Node)
边由校验矩阵 H 的 1 决定。译码迭代由两步交替:
1. VN -> CN 消息更新
2. CN -> VN 消息更新
4.3 译码算法(简化 Min-Sum)
在工程中常用 Min-Sum 及其修正版本(Normalized/Offset Min-Sum),原因是:
• 比 Sum-Product 更容易硬件化
• 复杂度低,性能接近可接受
CN 更新核心:
• 符号取邻居符号异或(或乘积)
• 幅值取最小值(或修正后的最小值)
VN 更新核心:
• 先验 LLR + 来自所有 CN 的外信息求和
判决:
• LLR < 0 判 1,否则判 0
• 满足全部校验方程可提前停止
---
5. LDPC 在 FPGA 中的实现方案
5.1 顶层模块划分建议
LLR Input Buffer
-> VN Update Engine
-> CN Update Engine
-> Hard Decision + Syndrome Check
-> Iteration Controller
-> Output Buffer
建议再加:
• 配置寄存器(码型/迭代上限/早停开关)
• 统计模块(迭代次数、失败计数、吞吐)
5.2 数据通路与存储组织
关键数据:
• 信道先验 LLR
• VN->CN 消息
• CN->VN 消息
• 硬判决比特
存储建议:
• 消息 RAM 双缓冲(ping-pong)
• 按校验层(layer)分块存储,适配 Layered Decoding
• 量化位宽固定点(如 6~8 bit)
5.3 调度策略
两种主流:
1. Flooding:全局轮次更新
2. Layered:分层更新(收敛更快,常更优)
工程上 Layered 常见优势:
• 同等性能下迭代次数更少
• 总时延更低
5.4 关键优化点
1. 定点量化优化:
• 位宽太小性能损失,太大资源/功耗上升
2. 早停(Early Stop):
• syndrome=0 时提前结束迭代
3. 并行度折中:
• 并行越高吞吐越高,但 BRAM 带宽和布线压力更大
4. 消息裁剪与饱和:
• 防止数值溢出,提高稳定性
---
6. 核心算法伪代码(LDPC Min-Sum)
6.1 解码主流程伪代码
input: llr_channel[N], H_structure, iter_max
state:
msg_v2c[edge_num]
msg_c2v[edge_num]
llr_apost[N]
init:
for each edge (v,c):
msg_v2c[v,c] = llr_channel[v]
for iter in 1..iter_max:
// CN update
for each check node c:
gather all incoming msg_v2c[* ,c]
sign_all = product(sign(msg_v2c))
min1, min2 = two_smallest(abs(msg_v2c))
for each neighbor v of c:
sign_out = sign_all * sign(msg_v2c[v,c])
mag_out = (abs(msg_v2c[v,c]) == min1) ? min2 : min1
msg_c2v[c,v] = sign_out * scale_or_offset(mag_out)
// VN update
for each variable node v:
sum_llr = llr_channel[v]
for each neighbor c of v:
sum_llr += msg_c2v[c,v]
llr_apost[v] = saturate(sum_llr)
for each neighbor c of v:
extrinsic = llr_apost[v] - msg_c2v[c,v]
msg_v2c[v,c] = saturate(extrinsic)
// hard decision + syndrome check
for v in 0..N-1:
hard[v] = (llr_apost[v] < 0) ? 1 : 0
if syndrome_ok(hard, H_structure):
return hard, iter, SUCCESS
return hard, iter_max, FAIL
6.2 Syndrome 检查伪代码
function syndrome_ok(hard_bits, H):
for each check node c:
parity = 0
for each v connected to c:
parity ^= hard_bits[v]
if parity != 0:
return false
return true
---
7. 性能、资源、功耗三者折中
7.1 吞吐估算(简化)
可粗估:
其中:
• N:码长
• R:码率
• fclₖ:时钟频率
• P:并行度
• Iavg:平均迭代次数
• C:每次迭代等效周期因子
结论:
• 降低平均迭代次数(如早停、layered)通常收益很大。
7.2 常见“看起来快、其实不优”的设计
1. 并行度盲目拉高:
• BRAM 端口不够,最终频率下降
2. 位宽盲目加大:
• 误码性能提升有限,资源与功耗显著增加
3. 不做早停:
• 平均时延和功耗都偏高
---
8. 测试与验证建议
8.1 功能验证
• 与软件黄金模型(Python/C)逐向量对比
• 覆盖不同 SNR、码率、码长
• 注入随机 bit 错误与 burst 错误
8.2 性能验证
• 吞吐(Gbps)
• 平均/最大迭代次数
• 时延分布
8.3 误码性能验证
• BER/FER 曲线
• 与浮点参考模型差距
• 不同量化位宽下性能对比
8.4 硬件实现验证
• 时序收敛(WNS/TNS)
• 资源占用(LUT/FF/BRAM/DSP)
• 功耗分析(动态/静态)
---
9. RS-FEC 编码/解码伪代码(工程补充)
> 这里给出通用 RS(n,k) 框架伪代码,便于对照硬件实现。不同标准(如 RS(544,514))参数不同,但流程一致。
9.1 RS-FEC 编码伪代码(系统码)
思路:
• 原始数据作为前 k 个符号;
• 用生成多项式对消息多项式做模运算得到 parity;
• 码字 = data || parity。
input:
data_sym[0..k-1] // GF(2^m) 符号
gen_poly[0..2t] // 生成多项式
state:
parity[0..2t-1] = 0
for i in 0..k-1:
feedback = data_sym[i] XOR parity[2t-1]
// LFSR 形式更新 parity 寄存器
for j in (2t-1) downto 1:
if feedback != 0:
parity[j] = parity[j-1] XOR gf_mul(feedback, gen_poly[j])
else:
parity[j] = parity[j-1]
if feedback != 0:
parity[0] = gf_mul(feedback, gen_poly[0])
else:
parity[0] = 0
codeword = concat(data_sym[0..k-1], parity[2t-1..0])
return codeword
9.2 RS-FEC 解码伪代码(硬判决,经典流程)
标准步骤:
1) 计算综合(Syndrome)
2) Berlekamp-Massey 求误差定位多项式
3) Chien 搜索找错误位置
4) Forney 算法求错误值
5) 修正码字
input:
recv[0..n-1]
// Step1: syndrome
for i in 1..2t:
S[i] = poly_eval(recv, alpha^i)
if all S[i] == 0:
return recv, NO_ERROR
// Step2: error locator polynomial
Lambda = berlekamp_massey(S)
// Step3: find error locations
err_pos = []
for p in 0..n-1:
if poly_eval(Lambda, alpha^(-p)) == 0:
err_pos.append(p)
if len(err_pos) > t:
return recv, DECODE_FAIL
// Step4: error magnitude
Omega = syndrome_to_omega(S, Lambda)
for each p in err_pos:
e = forney_eval(Omega, Lambda, p)
recv[p] = recv[p] XOR e
// Step5: optional re-check
recompute syndrome S2
if any S2 != 0:
return recv, DECODE_FAIL
return recv, DECODE_OK
9.3 FPGA 实现提示(RS-FEC)
• gf_mul/gf_inv 建议查表(LUT)或对数表(log/antilog)实现。
• Syndrome 计算可流水化,按符号流并行处理。
• Chien 搜索天然适合并行展开。
• Forney 可做时分复用降低资源。
---
10. 其他相关信息补充
10.1 标准与协议关联
不同协议会规定特定 FEC:
• 高速以太网常见 RS-FEC
• 5G 数据信道广泛使用 LDPC
工程上要先看标准,再定算法,不可反过来。
10.2 FEC 与系统架构关系
• FEC 放在 PHY/PCS 附近时,接口延迟与带宽规划要提前做
• FEC 与重传机制(ARQ/HARQ)是互补关系
• FEC 参数会影响整机功耗与热设计
10.3 何时不该上“重型 FEC”
• 链路本身误码很低且时延极敏感
• 资源预算极其紧张
• 协议并不要求该级别纠错
---
11. 初学者快速上手路径(建议)
1. 先实现 Hamming/BCH 小例子,理解编码-译码闭环
2. 再做 LDPC 简化版本(短码长、低并行)
3. 加入早停和量化优化
4. 最后做高吞吐流水与并行扩展
---
12. 一页总结
• FEC 的本质是“冗余换可靠性”。
• 常见算法各有适配场景:
• 简单检测:Parity
• 轻量纠错:Hamming
• 存储强纠错:BCH
• 突发错误友好:RS
• 现代高速通信主力:LDPC
• 以 LDPC 为例,FPGA 落地关键在:
• 消息存储组织
• 迭代调度(尤其 layered)
• 量化与早停策略
• 真正工程可用的 FEC 方案,需要同时满足:
• 误码性能目标
• 吞吐/时延目标
• 资源与功耗预算
---
附录A:FEC 方案选型速查表
| 场景 | 推荐算法 | 关注点 |
| ------------- | ---------------- | -------------------- |
| 低复杂度检测 | Parity/Hamming | 低开销、低时延 |
| NAND/存储控制 | BCH/LDPC | 多比特纠错能力 |
| 高速链路 | RS/LDPC | 吞吐、并行与标准兼容 |
| 无线数据面 | LDPC/Turbo/Polar | 性能与时延折中 |
---
> 注:不同标准版本和器件平台会影响最终算法选择与参数,请结合目标协议规范和 FPGA 资源报告做最终定型。