跳转至

第三章:编码解码原理

深入解析蓝牙信道编码技术:白化、前向纠错、交织、汉明码、卷积码的完整原理与实现


3.1 编码概述

3.1.1 编码的目的

无线通信中,信号传输会受到以下干扰:

  1. 加性高斯白噪声 (AWGN):热噪声引起的随机错误
  2. 多径衰落:信号反射导致的频率选择性衰落
  3. 突发干扰:WiFi、微波炉等同频段设备的脉冲干扰
  4. 多普勒频移:移动引起的频率偏移

编码的作用:

1
2
3
4
5
6
原始数据 → 信道编码 → 添加冗余 → 接收端检错/纠错 → 恢复原始数据

目标:
├── 检测传输错误
├── 纠正一定数量的错误
└── 降低重传概率,提高有效吞吐量

3.1.2 蓝牙编码流程

经典蓝牙发送端编码流程:

┌─────────────────────────────────────────────────────────────────┐
│                        发送端编码                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  原始数据    白化      FEC 编码     交织      调制      RF 发送  │
│     │        │           │          │         │          │      │
│     ▼        ▼           ▼          ▼         ▼          ▼      │
│  ┌─────┐  ┌─────┐    ┌─────┐    ┌─────┐   ┌─────┐    ┌─────┐  │
│  │数据 │─►│异或 │───►│添加 │───►│块交织│──►│GFSK │───►│天线 │  │
│  │流   │  │PN 序列│   │冗余 │    │      │   │调制 │    │     │  │
│  └─────┘  └─────┘    └─────┘    └─────┘   └─────┘    └─────┘  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                        接收端解码                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  RF 接收    解调      去交织     FEC 解码    去白化    恢复数据  │
│     │        │           │          │         │          │      │
│     ▼        ▼           ▼          ▼         ▼          ▼      │
│  ┌─────┐  ┌─────┐    ┌─────┐    ┌─────┐   ┌─────┐    ┌─────┐  │
│  │天线 │─►│GFSK │───►│块去交织│─►│纠错 │──►│异或 │───►│数据 │  │
│  │     │  │解调 │    │      │    │      │   │PN 序列│   │流   │  │
│  └─────┘  └─────┘    └─────┘    └─────┘   └─────┘    └─────┘  │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

BLE 编码流程:

┌───────────────────────────────────────────────────────────────┐
│                    BLE 编码流程 (LE Coded PHY)                 │
├───────────────────────────────────────────────────────────────┤
│                                                               │
│  数据 → CRC → FEC 编码 → 码片映射 → 调制                       │
│        (32bit)  (1/3 码率)  (S=2 或 S=8)                       │
│                                                               │
│  FEC 编码输出结构:                                            │
│  ┌────────┬────────┬────────┬────────┐                        │
│  │  Header│  PDU   │  CRC   │  Tail  │                        │
│  │ (8bit) │(可变)  │(24bit) │(6bit)  │                        │
│  └────────┴────────┴────────┴────────┘                        │
│       │        │        │        │                             │
│       └────────┴────────┴────────┘                             │
│                    │                                           │
│                    ▼                                           │
│              FEC 编码 (1/3 码率)                                 │
│                    │                                           │
│                    ▼                                           │
│              码片映射 (S=2 或 S=8)                               │
│                                                               │
└───────────────────────────────────────────────────────────────┘

3.2 白化 (Whitening)

3.2.1 白化的目的

问题: - 长串连续的 0 或 1 会导致: - 接收端时钟恢复困难 - 频谱能量集中,不符合频谱模板要求 - DC 分量过大,影响交流耦合电路

解决方案: - 使用伪随机噪声 (PN) 序列与数据异或 - 使输出数据接近随机分布 - 频谱能量均匀分布

3.2.2 蓝牙白化算法

经典蓝牙白化多项式:

生成多项式:P(x) = x⁷ + x⁴ + 1

LFSR 结构:

    ┌───┐    ┌───┐    ┌───┐    ┌───┐    ┌───┐    ┌───┐    ┌───┐
    │ D7│───►│ D6│───►│ D5│───►│ D4│───►│ D3│───►│ D2│───►│ D1│
    └─┬─┘    └─┬─┘    └─┬─┘    └─┬─┘    └─┬─┘    └─┬─┘    └─┬─┘
      │        │        │        │        │        │        │
      │        │        │        └───┐    │        │        │
      │        │        │            │    │        │        │
      │        │        │      ┌─────┴────┴────┐   │        │
      │        │        │      │   XOR Gate   │   │        │
      │        │        │      └──────┬───────┘   │        │
      │        │        │             │           │        │
      │        │        │             ▼           │        │
      │        │        │         ┌───────┐       │        │
      │        │        └────────►│  XOR  │◄──────┘        │
      │        │                  └───┬───┘                │
      │        │                      │                    │
      │        └──────────────────────┼────────────────────┘
      │                               │
      │                               ▼
      │                           输出位
      └──────────────────────────────┘
              反馈到 D7 输入

初始值:由蓝牙地址决定 (非全 0)

Verilog 实现:

module bluetooth_whitener (
    input wire clk,
    input wire reset_n,
    input wire data_in,
    output reg data_out,
    input wire enable
);

// 7 位 LFSR 寄存器
reg [6:0] lfsr;

// 白化多项式:x^7 + x^4 + 1
// 反馈抽头:bit 6 和 bit 3 (对应 x^7 和 x^4)
wire feedback;
assign feedback = lfsr[6] ^ lfsr[3];

// LFSR 更新
always @(posedge clk or negedge reset_n) begin
    if (!reset_n) begin
        lfsr <= 7'b1010101;  // 非零初始值
    end else if (enable) begin
        lfsr <= {lfsr[5:0], feedback};  // 左移,反馈到最低位
    end
end

// 白化输出:数据与 LFSR 最高位异或
always @(posedge clk) begin
    if (enable) begin
        data_out <= data_in ^ lfsr[6];
    end
end

endmodule

BLE 白化:

1
2
3
4
5
6
7
8
9
BLE 使用相同的白化多项式:x⁷ + x⁴ + 1

区别:
├── 初始值由接入地址 (Access Address) 决定
├── 每个包重新初始化 LFSR
└── 白化序列长度 = 包长度

初始值计算:
lfsr_initial = access_address[6:0]

3.2.3 去白化

接收端去白化:

原理:白化的逆操作 = 再次与相同 PN 序列异或

证明:
发送:y = x ⊕ p
接收:y' = y (假设无错误)
解码:x' = y' ⊕ p = (x ⊕ p) ⊕ p = x

关键:收发双方 LFSR 必须同步
├── 相同的多项式
├── 相同的初始值
└── 相同的时钟

Verilog 实现:

module bluetooth_dewhitener (
    input wire clk,
    input wire reset_n,
    input wire data_in,
    output reg data_out,
    input wire enable,
    input wire [6:0] init_value  // 初始值输入
);

reg [6:0] lfsr;
wire feedback;
assign feedback = lfsr[6] ^ lfsr[3];

always @(posedge clk or negedge reset_n) begin
    if (!reset_n) begin
        lfsr <= init_value;  // 使用传入的初始值
    end else if (enable) begin
        lfsr <= {lfsr[5:0], feedback};
    end
end

always @(posedge clk) begin
    if (enable) begin
        data_out <= data_in ^ lfsr[6];  // 异或去白化
    end
end

endmodule

3.3 前向纠错 (FEC)

3.3.1 FEC 基本原理

核心思想:

在原始数据中添加冗余信息
接收端利用冗余检测并纠正错误

编码效率 (码率) = k / n
其中:
├── k: 原始数据位数
├── n: 编码后总位数
└── 冗余位 = n - k

码率越低:
├── 冗余越多
├── 纠错能力越强
└── 有效数据率越低

3.3.2 经典蓝牙 FEC 方案

方案 1: ⅓ FEC (用于 DM 包)

编码规则:每个 bit 重复 3 次

原始:0 → 编码:000
原始:1 → 编码:111

解码规则:多数表决

接收:000 → 解码:0
接收:001 → 解码:0 (纠正 1 个错误)
接收:011 → 解码:1 (纠正 1 个错误)
接收:111 → 解码:1

纠错能力:
├── 可纠正:1 bit 错误/3bit 组
├── 可检测:2 bit 错误/3bit 组
└── 码率:1/3

优点:实现简单
缺点:冗余大,效率低

Verilog 实现 (⅓ FEC 编码器):

module fec_1_3_encoder (
    input wire clk,
    input wire reset_n,
    input wire data_in,
    output reg data_out,
    input wire enable
);

reg [1:0] repeat_count;

always @(posedge clk or negedge reset_n) begin
    if (!reset_n) begin
        repeat_count <= 2'b00;
        data_out <= 1'b0;
    end else if (enable) begin
        if (repeat_count == 2'b00) begin
            data_out <= data_in;
            repeat_count <= 2'b01;
        end else if (repeat_count == 2'b01) begin
            data_out <= data_in;
            repeat_count <= 2'b10;
        end else begin
            data_out <= data_in;
            repeat_count <= 2'b00;
        end
    end
end

endmodule

Verilog 实现 (⅓ FEC 解码器):

module fec_1_3_decoder (
    input wire clk,
    input wire reset_n,
    input wire data_in,
    output reg data_out,
    input wire enable
);

reg [2:0] shift_reg;
reg [1:0] count;

always @(posedge clk or negedge reset_n) begin
    if (!reset_n) begin
        shift_reg <= 3'b000;
        count <= 2'b00;
        data_out <= 1'b0;
    end else if (enable) begin
        // 移位寄存器存储 3 个接收位
        shift_reg <= {shift_reg[1:0], data_in};
        count <= count + 1;

        // 每 3 位输出一次
        if (count == 2'd2) begin
            // 多数表决
            data_out <= (shift_reg[0] + shift_reg[1] + shift_reg[2]) >= 2;
            count <= 2'b00;
        end
    end
end

endmodule

方案 2: ⅔ FEC (汉明码,用于 DV 包)

汉明码 (15, 10):
├── 输入:10 bit 数据
├── 输出:15 bit 码字 (10 数据位 + 5 校验位)
├── 码率:2/3
└── 纠错能力:1 bit 错误

生成矩阵方法:
设数据位为 d[9:0]
校验位 p[4:0] 计算如下:

p[0] = d[0] ⊕ d[1] ⊕ d[3] ⊕ d[4] ⊕ d[6] ⊕ d[8]
p[1] = d[0] ⊕ d[2] ⊕ d[3] ⊕ d[5] ⊕ d[6] ⊕ d[9]
p[2] = d[1] ⊕ d[2] ⊕ d[3] ⊕ d[7] ⊕ d[8] ⊕ d[9]
p[3] = d[4] ⊕ d[5] ⊕ d[6] ⊕ d[7] ⊕ d[8]
p[4] = d[0] ⊕ d[1] ⊕ d[2] ⊕ d[4] ⊕ d[5] ⊕ d[7]

编码后码字:[d9,d8,d7,d6,d5,d4,d3,d2,d1,d0,p4,p3,p2,p1,p0]

汉明码解码 (伴随式解码):

接收端计算伴随式 (Syndrome):

设接收码字为 r[14:0]

s[0] = r[0] ⊕ r[1] ⊕ r[3] ⊕ r[4] ⊕ r[6] ⊕ r[8] ⊕ r[10]
s[1] = r[0] ⊕ r[2] ⊕ r[3] ⊕ r[5] ⊕ r[6] ⊕ r[9] ⊕ r[11]
s[2] = r[1] ⊕ r[2] ⊕ r[3] ⊕ r[7] ⊕ r[8] ⊕ r[9] ⊕ r[12]
s[3] = r[4] ⊕ r[5] ⊕ r[6] ⊕ r[7] ⊕ r[8] ⊕ r[13]
s[4] = r[0] ⊕ r[1] ⊕ r[2] ⊕ r[4] ⊕ r[5] ⊕ r[7] ⊕ r[14]

伴随式 s[4:0] 与错误位置的映射:

s[4:0]    错误位置
00000    无错误
00001    r[0] 错误
00010    r[1] 错误
...
11111    r[30] 错误 (超出范围,不可纠正)

纠错:将错误位置的 bit 取反

3.3.3 BLE FEC 方案

LE Coded PHY 的 FEC 编码:

编码结构:

┌─────────────────────────────────────────────────────────┐
│                    编码前数据                            │
│  ┌─────────┬─────────────┬─────────┐                    │
│  │  Header │  Payload    │   CRC   │                    │
│  │  8 bit  │  可变长度   │ 24 bit  │                    │
│  └─────────┴─────────────┴─────────┘                    │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                    FEC 编码 (1/3 码率)                     │
│                                                          │
│  编码规则:每个 bit 映射为 3 个码片                         │
│                                                          │
│  0 → 000                                                 │
│  1 → 111                                                 │
│                                                          │
│  但实际使用更复杂的映射以提高性能                          │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│                    码片映射                               │
│                                                          │
│  S=2 模式:每 2 个码片表示 1 个符号                          │
│  S=8 模式:每 8 个码片表示 1 个符号                          │
│                                                          │
└─────────────────────────────────────────────────────────┘

FEC 块结构:

1
2
3
4
5
6
7
8
FEC 编码将数据分为多个 FEC 块:

┌─────────────────────────────────────────────────────────┐
│  FECBlock 0  │  FECBlock 1  │  FECBlock 2  │  ...      │
│  (64 bit)   │  (64 bit)   │  (64 bit)   │            │
└─────────────────────────────────────────────────────────┘

每个 FEC 块独立编码,便于并行处理

3.4 交织 (Interleaving)

3.4.1 交织的目的

问题:突发错误

1
2
3
4
5
6
7
8
9
无线信道中的干扰通常是突发的:
├── WiFi 包干扰:持续几百微秒
├── 微波炉泄漏:脉冲噪声
└── 多径衰落:深衰落持续多个符号

突发错误会超过 FEC 的纠错能力

例如:1/3 FEC 只能纠正每组 1 个错误
如果连续 3 个错误 → 无法纠正

解决方案:交织

交织原理:将连续的错误分散到不同的 FEC 组

发送端:
原始数据:[d0, d1, d2, d3, d4, d5, d6, d7, ...]
         ▼ (写入交织器)
┌─────────────────┐
│ d0  d1  d2  d3  │
│ d4  d5  d6  d7  │
│ d8  d9  d10 d11 │
└─────────────────┘
         ▼ (按列读出)
交织数据:[d0, d4, d8, d1, d5, d9, d2, d6, d10, ...]

接收端:
收到突发错误可能影响连续的交织数据
         ▼ (写入去交织器)
┌─────────────────┐
│ d0  d4  d8  ?   │
│ ?   d5  d9  ?   │
│ d2  d6  d10 ... │
└─────────────────┘
         ▼ (按行读出)
去交织后:[d0, d1, d2, d3, d4, d5, d6, d7, ...]

结果:突发错误被分散,每个 FEC 组只有 1 个错误 → 可纠正

3.4.2 蓝牙交织方案

经典蓝牙块交织:

交织器尺寸:根据包类型而定

DH1 包 (无 FEC):不交织
DM1 包 (2/3 FEC):交织

DM1 交织方案:
输入:10 个数据位 + 5 个校验位 = 15 位
交织矩阵:3 行 × 5 列

写入 (按行):
┌───────────────────┐
│ d0  d1  d2  d3  d4│
│ d5  d6  d7  d8  d9│
│ p0  p1  p2  p3  p4│
└───────────────────┘

读出 (按列):
[d0, d5, p0, d1, d6, p1, d2, d7, p2, d3, d8, p3, d4, d9, p4]

Verilog 实现 (3×5 块交织器):

module bluetooth_interleaver (
    input wire clk,
    input wire reset_n,
    input wire [14:0] data_in,  // 15 位输入
    output reg [14:0] data_out, // 15 位输出
    input wire enable
);

// 3×5 交织矩阵
reg [4:0] matrix [0:2];

// 写入阶段
always @(posedge clk or negedge reset_n) begin
    if (!reset_n) begin
        matrix[0] <= 5'b00000;
        matrix[1] <= 5'b00000;
        matrix[2] <= 5'b00000;
    end else if (enable) begin
        // 按行写入
        matrix[0] <= data_in[14:10];
        matrix[1] <= data_in[9:5];
        matrix[2] <= data_in[4:0];
    end
end

// 读出阶段 (按列)
always @(posedge clk) begin
    if (enable) begin
        data_out[14] <= matrix[0][4];  // d0
        data_out[13] <= matrix[1][4];  // d5
        data_out[12] <= matrix[2][4];  // p0
        data_out[11] <= matrix[0][3];  // d1
        data_out[10] <= matrix[1][3];  // d6
        data_out[9]  <= matrix[2][3];  // p1
        data_out[8]  <= matrix[0][2];  // d2
        data_out[7]  <= matrix[1][2];  // d7
        data_out[6]  <= matrix[2][2];  // p2
        data_out[5]  <= matrix[0][1];  // d3
        data_out[4]  <= matrix[1][1];  // d8
        data_out[3]  <= matrix[2][1];  // p3
        data_out[2]  <= matrix[0][0];  // d4
        data_out[1]  <= matrix[1][0];  // d9
        data_out[0]  <= matrix[2][0];  // p4
    end
end

endmodule

3.4.3 卷积交织

卷积交织器结构:

相比块交织,卷积交织延迟更小

结构:
输入 ──┬──► [D0] ──┬──► 输出
       │          │
       ├──► [D1] ─┤
       │          │
       ├──► [D2] ─┤
       │          │
       └──► [D3] ─┘

其中 [Dn] 表示 n 级延迟单元

每个输入符号轮流进入不同支路
输出时按顺序合并

3.5 卷积码

3.5.1 卷积码原理

与分组码的区别:

1
2
3
4
5
6
7
8
9
分组码 (如汉明码):
├── 固定长度的输入块
├── 独立编码每个块
└── 无记忆性

卷积码:
├── 连续的数据流
├── 当前输出依赖当前和之前的输入
└── 有记忆性 (约束长度)

卷积码参数:

1
2
3
4
5
6
7
8
9
(n, k, K) 卷积码:
├── n: 输出比特数/时钟周期
├── k: 输入比特数/时钟周期
└── K: 约束长度 (移位寄存器级数 +1)

蓝牙 EDR 使用 (2, 1, 4) 卷积码:
├── 每时钟输入 1 bit
├── 每时钟输出 2 bit
└── 约束长度 K=4 (3 级移位寄存器)

3.5.2 蓝牙 EDR 卷积码

编码器结构:

输入 ──► D ──► D ──► D ──►
         │     │     │     │
         │     │     │     │
         ⊕     ⊕     │     │
         │     │     │     │
输出 1 ◄─┘     │     │     │
               │     │     │
               ⊕     ⊕     │
               │     │     │
输出 2 ◄───────┘     │     │
                     │     │
                     ⊕     │
                     │     │
输出 3 ◄─────────────┘     │

生成多项式:
G1 = 1 + D + D² + D³  (1111)
G2 = 1 + D² + D³      (1011)
G3 = 1 + D + D³       (1101)

码率:1/2 或 1/3 (通过打孔调整)

状态转移图:

状态由移位寄存器内容定义 (3 位 = 8 个状态)

状态:S0(000), S1(001), S2(010), S3(011)
     S4(100), S5(101), S6(110), S7(111)

转移:
S0 --0--> S0 (输出 00)
S0 --1--> S1 (输出 11)
S1 --0--> S2 (输出 10)
S1 --1--> S3 (输出 01)
...

 trellis 图用于 Viterbi 解码

3.5.3 Viterbi 解码

Viterbi 算法原理:

最大似然序列估计 (MLSE)

核心思想:
1. 构建 trellis 图 (状态转移图)
2. 计算每条路径的度量 (与接收序列的距离)
3. 在每个状态保留最优路径 (幸存路径)
4. 回溯得到最可能的发送序列

算法步骤:

初始化:
├── 设置初始状态度量 (S0=0, 其他=∞)
└── 清空幸存路径存储器

迭代 (每个接收符号):
├── 计算分支度量 (接收符号与期望符号的距离)
├── 更新路径度量 (累加分支度量)
├── 比较进入同一状态的路径
└── 保留度量最小的路径 (ACS 操作)

回溯:
├── 从最终状态回溯幸存路径
└── 得到解码输出

Viterbi 解码器 Verilog 框架:

module viterbi_decoder (
    input wire clk,
    input wire reset_n,
    input wire [1:0] soft_input,  // 软判决输入
    output reg data_out,
    input wire enable
);

// 8 个状态的路径度量
reg [7:0] path_metric [0:7];

// 幸存路径存储器
reg [31:0] survivor_path [0:7];

// ACS (Add-Compare-Select) 单元
wire [7:0] branch_metric [0:15];
wire [7:0] new_metric [0:7];
wire [1:0] select [0:7];

// 分支度量计算 (欧氏距离)
genvar i;
generate
    for (i = 0; i < 16; i = i + 1) begin
        assign branch_metric[i] = calc_branch_metric(soft_input, i);
    end
endgenerate

// ACS 操作
always @(posedge clk) begin
    // 加:计算新路径度量
    // 比:比较进入同一状态的两条路径
    // 选:保留较优路径
    // (详细实现略)
end

// 回溯
always @(posedge clk) begin
    // 从最优状态回溯得到解码输出
    // (详细实现略)
end

endmodule

3.6 循环冗余校验 (CRC)

3.6.1 CRC 原理

CRC 作用: - 检测数据传输错误 - 不能纠错,只能检错 - 检错能力强于简单校验和

蓝牙 CRC 多项式:

1
2
3
4
5
6
7
经典蓝牙:CRC-24
生成多项式:G(x) = x²⁴ + x¹⁰ + x⁸ + x⁷ + x⁶ + x⁴ + x² + 1
          = 0x15B705 (十六进制)

BLE: CRC-24 (不同多项式)
生成多项式:G(x) = x²⁴ + x¹⁰ + x⁹ + x⁸ + x⁶ + x⁵ + x⁴ + x³ + x + 1
          = 0x165B705 (十六进制)

3.6.2 CRC 计算

串行 CRC 计算器:

输入数据 ──► ⊕ ──► D ──► D ──► ... ──► D (24 级)
             ▲     │     │           │
             │     │     │           │
             └─────┴─────┴───────────┘
                   │     │           │
                   ⊕     ⊕           ⊕
                   │     │           │
                   └─────┴───────────┘
                      CRC 输出

抽头位置由生成多项式决定

Verilog 实现 (CRC-24):

module crc24_generator (
    input wire clk,
    input wire reset_n,
    input wire data_in,
    output reg [23:0] crc_out,
    input wire enable,
    input wire calc_start,
    output reg calc_done
);

reg [23:0] crc_reg;
wire [23:0] next_crc;

// CRC-24 蓝牙多项式:x^24 + x^10 + x^8 + x^7 + x^6 + x^4 + x^2 + 1
// 抽头位置:23, 9, 7, 6, 5, 3, 1, 0

assign next_crc[23] = crc_reg[22];
assign next_crc[22] = crc_reg[21];
assign next_crc[21] = crc_reg[20];
assign next_crc[20] = crc_reg[19];
assign next_crc[19] = crc_reg[18];
assign next_crc[18] = crc_reg[17];
assign next_crc[17] = crc_reg[16];
assign next_crc[16] = crc_reg[15];
assign next_crc[15] = crc_reg[14];
assign next_crc[14] = crc_reg[13];
assign next_crc[13] = crc_reg[12];
assign next_crc[12] = crc_reg[11];
assign next_crc[11] = crc_reg[10];
assign next_crc[10] = crc_reg[9] ^ crc_reg[23] ^ data_in;
assign next_crc[9]  = crc_reg[8];
assign next_crc[8]  = crc_reg[7] ^ crc_reg[23] ^ data_in;
assign next_crc[7]  = crc_reg[6] ^ crc_reg[23] ^ data_in;
assign next_crc[6]  = crc_reg[5] ^ crc_reg[23] ^ data_in;
assign next_crc[5]  = crc_reg[4];
assign next_crc[4]  = crc_reg[3] ^ crc_reg[23] ^ data_in;
assign next_crc[3]  = crc_reg[2];
assign next_crc[2]  = crc_reg[1] ^ crc_reg[23] ^ data_in;
assign next_crc[1]  = crc_reg[0];
assign next_crc[0]  = crc_reg[23] ^ data_in;

always @(posedge clk or negedge reset_n) begin
    if (!reset_n) begin
        crc_reg <= 24'h000000;
        calc_done <= 1'b0;
    end else if (enable) begin
        if (calc_start) begin
            crc_reg <= 24'h555555;  // 初始值
            calc_done <= 1'b0;
        end else begin
            crc_reg <= next_crc;
            calc_done <= 1'b1;
        end
    end
end

assign crc_out = crc_reg;

endmodule

3.7 编码性能对比

3.7.1 误码率性能

BER vs SNR 性能对比 (AWGN 信道):

SNR (dB)    无编码    1/3 FEC    2/3 FEC    卷积码
─────────────────────────────────────────────────
  0         0.08      0.01       0.03       0.02
  2         0.05      0.001      0.01       0.005
  4         0.02      0.0001     0.003      0.001
  6         0.005     0.00001    0.001      0.0003
  8         0.001     <10⁻⁶      0.0003     0.0001
 10         0.0002    <10⁻⁷      0.0001     <10⁻⁵

结论:
├── 1/3 FEC 在低 SNR 下性能最好
├── 卷积码在中高 SNR 下性能最优
└── 无编码需要 SNR > 10 dB 才能达到可接受 BER

3.7.2 编码效率

有效数据率对比:

编码方案    码率    开销    适用场景
─────────────────────────────────────
无编码      1       0%      高 SNR, 低延迟
1/3 FEC     1/3     200%    低 SNR, 高可靠性
2/3 FEC     2/3     50%     中等 SNR
卷积码 1/2  1/2     100%    连续数据流
卷积码 2/3  2/3     50%     打孔后
LE Coded S=2 1/2   100%    BLE 长距离
LE Coded S=8 1/8   700%    BLE 超长距离

3.8 本章小结

本章深入讲解了蓝牙编码解码的核心技术:

  1. 白化:PN 序列异或,频谱均匀化,LFSR 实现
  2. FEC:⅓ 重复码、⅔ 汉明码、BLE 的 ⅓ 码率 FEC
  3. 交织:块交织、卷积交织,分散突发错误
  4. 卷积码:EDR 使用,Viterbi 解码
  5. CRC:24 位循环冗余校验,错误检测

这些技术共同保证了蓝牙在复杂无线环境中的可靠通信。

下一章将讲解调制解调技术的详细实现。


上一章:02-物理层详解
下一章:04-调制解调技术