本文基于IEEE Std 802.3-2022 49章,本章介绍了10GBASE-R的PCS(Physical Coding Sublayer,物理编码子层)64b/66b原理,其中包括加解扰过程。
基本概念
加扰(Scrambling) 是一种数据变换技术,通过特定的算法将原始数据序列与伪随机序列进行异或运算,使输出数据呈现出类似随机噪声的统计特性。

解扰(Descrambling) 则是加扰的逆过程,使用相同的伪随机序列与接收到的加扰数据进行异或运算,恢复出原始数据。

上图中:
发送端扰码公式:
其中 d(n) 是原始数据,s(n) 是扰码后输出。
接收端解扰公式:
其中 r(n) 是接收到的数据(理想情况下 r(n)=s(n)),代入后可以得到。
注意:解扰器只依赖接收到的 r(n),不依赖原始数据或初始状态!这是因为即使接收端 LFSR 初始状态错误,经过最多 N 比特(N = 最大抽头延迟,如 58)后,内部状态会自动“被正确数据覆盖”而收敛到正确状态。
以一个简单的多项式为例:
扰码公式(发送端):
解扰公式(接收端):
假设接收端初始寄存器为 [?, ?, ?](未知),但一旦开始接收 r(0),r(1),r(2),…,从第 3 个比特起:
即使 r(0) 被错误地用于反馈,但从 n=3 开始,所有用于反馈的 r(n−k) 都是真实的扰码输出,因此解扰结果立即正确!即只要连续接收到 N+1 个正确的扰码比特(N 为最大延迟),解扰器就能自动输出正确的原始数据,无需知道初始状态。
串行LFSR加扰
直接根据加扰的多项式可以很方便写出代码,每个时钟周期仅输入1bit数据,对应1bit数据输出,同时LFSR中的状态全部更新。
module scr_66b_s (
input clk,
input rst_n, // 异步复位,低有效
input data_in, // 串行输入数据
input scram_en, // 加扰使能(高有效)
output data_out // 加扰后串行输出
);
// 58位移位寄存器,对应多项式最高次 x^58
reg [57:0] lfsr;
// 反馈抽头:x^39 和 x^58
// 寄存器索引:bit[38]对应x^39,bit[57]对应x^58
wire feedback;
assign feedback = lfsr[38] ^ lfsr[57];
// 自同步加扰:输出 = 输入 XOR 反馈
// 加扰结果同时反馈到LFSR的输入端(LSB)
assign data_out = scram_en ? (data_in ^ feedback) : data_in;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
lfsr <= 58'h0; // 复位归零
end else if (scram_en) begin
// 移位寄存器左移,新 bit[0] = 加扰输出(data_out)
lfsr <= {lfsr[56:0], data_out};
end
end
endmodule并行LFSR加扰
很多时候输入数据并不是单比特信号,需要对上述的加扰过程进行改造,在同一个时钟周期完成多bit数据加扰,可以极大提升系统数据处理的速度,这也是现代通信中常用的加扰方式。
module scr_66b (
input clk,
input rst_n, // 异步复位,低有效
input [63:0] i_dat, // 并行输入数据,bit[0]为串行时序最先输入的位
input i_dat_vld,
input scram_en, // 加扰使能(高有效)
output reg o_dat_vld,
output [63:0] o_dat // 并行输出数据
);
reg [57:0] lfsr;
reg [63:0] data_out_w;
integer i;
reg [57:0] lfsr_temp;
reg [63:0] out_temp;
always @(*) begin
lfsr_temp = lfsr;
for (i = 0; i < 64; i = i + 1) begin
// 自同步加扰:out[i] = in[i] ^ (lfsr[38] ^ lfsr[57])
out_temp[i] = i_dat[i] ^ lfsr_temp[38] ^ lfsr_temp[57];
// LFSR左移,移入当前加扰输出
lfsr_temp = {lfsr_temp[56:0], out_temp[i]};
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
lfsr <= 58'h0;
end else if (i_dat_vld) begin
lfsr <= lfsr_temp;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
data_out_w <= 64'h0;
o_dat_vld <= 1'd0;
end else if (i_dat_vld) begin
data_out_w <= scram_en ? out_temp : i_dat; // 旁路模式
o_dat_vld <= i_dat_vld;
end
else begin
o_dat_vld <= 1'd0;
data_out_w <= data_out_w;
end
end
assign o_dat = data_out_w;
endmoduleVerilog设计:LFSR并行加解扰实现
https://blog.songshiyu.cn/archives/verilogshe-ji-lfsrbing-xing-jia-jie-rao-shi-xian

评论