一、什么是加扰、解扰?(大白话版)
很多新手会把加扰当成加密,这是最大误区!
- 加扰器 Scrambler
场景:串口、高速传输、视频数据传输
问题:如果长时间连续发 00000000 或 11111111,接收端抓不到时钟,传输会出错。
加扰作用:
把规整的 0、1 序列,打乱成看起来随机的 01 交替序列。
- 解扰器 Descrambler
加扰过的数据,接收端必须用一模一样的规则打乱一次,就能恢复原始数据。
核心黄金公式:
原始数据 ^ 随机扰码 = 加扰数据
加扰数据 ^ 随机扰码 = 原始数据
加扰和解扰电路结构完全一致!
二、本次设计参数(工程标准参数)
-
阶数:8 阶 LFSR
-
生成多项式(八进制 453):x\^8+x\^5+x\^3+1
-
初始值(初相):11111111
-
输出方式:取寄存器最高位作为扰码输出
-
移位规则:只有数据有效时才移位,空闲保持不动
八进制 453 解析:
-
453 → 二进制 100101011
-
对应抽头:第 8 位、第 5 位、第 3 位
-
代码下标从 0 开始 → bit7 ^ bit4 ^ bit2
三、整体工作原理(超通俗)
-
内部有 8 个小盒子(8bit 寄存器),初始全部装 1
-
固定三个盒子做异或运算,算出一个新数字
-
所有盒子整体右移,新数字补到最右侧
-
每次拿最左侧盒子的值和输入数据异或 → 加扰输出
-
接收端用完全一样的电路再异或一次 → 还原原始数据
四、加扰器 Verilog 完整代码
module scrambler
(
input iw_clk_p_g,
input iw_Rst_l, // 低电平复位
input iw_Data_Valid_h, // 数据有效标志
input iw_Data, // 原始输入比特
output reg ow_Scrambler_Valid_h,
output reg ow_Scrambler_Out
);
// 8位移位寄存器(8个小盒子)
reg 7:0 lfsr_reg;
// 固定抽头反馈:x^8+x^5+x^3+1
wire feedback = lfsr_reg7 ^ lfsr_reg4 ^ lfsr_reg2;
always @(posedge iw_clk_p_g or negedge iw_Rst_l) begin
if(!iw_Rst_l) begin
lfsr_reg <= 8'b11111111;
ow_Scrambler_Valid_h <= 1'b0;
ow_Scrambler_Out <= 1'b0;
end
else begin
ow_Scrambler_Valid_h <= iw_Data_Valid_h;
if(iw_Data_Valid_h) begin
// 最高位异或输入数据,完成加扰
ow_Scrambler_Out <= iw_Data ^ lfsr_reg7;
// 整体右移,补入反馈值
lfsr_reg <= {lfsr_reg6:0, feedback};
end
else begin
// 无数据时,寄存器保持不动
lfsr_reg <= lfsr_reg;
end
end
end
endmodule
五、解扰器 Verilog 完整代码
重点:解扰器电路和加扰器完全一样
因为:数据^扰码^扰码 = 原数据
module descrambler
(
input iw_clk_p_g,
input iw_Rst_l,
input iw_Data_Valid_h,
input iw_Data, // 输入:加扰后的数据
output reg ow_Descrambler_Valid_h,
output reg ow_Descrambler_Out // 输出:还原后的原始数据
);
reg 7:0 lfsr_reg;
wire feedback = lfsr_reg7 ^ lfsr_reg4 ^ lfsr_reg2;
always @(posedge iw_clk_p_g or negedge iw_Rst_l) begin
if(!iw_Rst_l) begin
lfsr_reg <= 8'b11111111;
ow_Descrambler_Valid_h <= 1'b0;
ow_Descrambler_Out <= 1'b0;
end
else begin
ow_Descrambler_Valid_h <= iw_Data_Valid_h;
if(iw_Data_Valid_h) begin
ow_Descrambler_Out <= iw_Data ^ lfsr_reg7;
lfsr_reg <= {lfsr_reg6:0, feedback};
end
else begin
lfsr_reg <= lfsr_reg;
end
end
end
endmodule
六、顶层联调模块(加扰 + 解扰直通测试)
直接把加扰输出接到解扰输入,仿真可看到:输入 = 最终输出,验证功能正确。
module top_scramble_descramble
(
input iw_clk_p_g,
input iw_Rst_l,
input iw_Data_Valid_h,
input iw_Data,
output scramble_out,
output descramble_out,
output data_valid
);
wire scr_valid;
scrambler u_scrambler(
.iw_clk_p_g(iw_clk_p_g),
.iw_Rst_l(iw_Rst_l),
.iw_Data_Valid_h(iw_Data_Valid_h),
.iw_Data(iw_Data),
.ow_Scrambler_Valid_h(scr_valid),
.ow_Scrambler_Out(scramble_out)
);
descrambler u_descrambler(
.iw_clk_p_g(iw_clk_p_g),
.iw_Rst_l(iw_Rst_l),
.iw_Data_Valid_h(scr_valid),
.iw_Data(scramble_out),
.ow_Descrambler_Valid_h(data_valid),
.ow_Descrambler_Out(descramble_out)
);
endmodule
七、完整 Testbench 仿真文件
`timescale 1ns / 1ps
module tb_top;
reg iw_clk_p_g;
reg iw_Rst_l;
reg iw_Data_Valid_h;
reg iw_Data;
wire scramble_out;
wire descramble_out;
wire data_valid;
top_scramble_descramble u_top(
.iw_clk_p_g(iw_clk_p_g),
.iw_Rst_l(iw_Rst_l),
.iw_Data_Valid_h(iw_Data_Valid_h),
.iw_Data(iw_Data),
.scramble_out(scramble_out),
.descramble_out(descramble_out),
.data_valid(data_valid)
);
// 时钟 100MHz
initial begin
iw_clk_p_g = 0;
forever #5 iw_clk_p_g = ~iw_clk_p_g;
end
initial begin
iw_Rst_l = 0;
iw_Data_Valid_h = 0;
iw_Data = 0;
#20;
iw_Rst_l = 1;
#10;
// 连续发送20组随机数据
repeat(20) begin
@(posedge iw_clk_p_g);
iw_Data_Valid_h = 1'b1;
iw_Data = $random;
end
@(posedge iw_clk_p_g);
iw_Data_Valid_h = 1'b0;
#50;
$finish;
end
// 保存波形
initial begin
$dumpfile("wave.vcd");
$dumpvars(0,tb_top);
end
endmodule
八、仿真结果结论(必看知识点)
- 原始输入数据 和 最终解扰输出完全一致
证明:加扰、解扰功能完全正确
- 中间的 scramble_out 是杂乱随机序列
证明:成功打散了连续 0/1,满足传输同步要求
- 无数据时寄存器保持静止,不空移位,符合工业标准
九、新手常见坑总结
坑 1:误以为加扰是加密
错!
加扰是可逆、无密钥、标准化打乱,任何人用同款多项式都能解,不具备加密安全性。
坑 2:空闲时刻不停移位
很多网上代码:不管有没有数据,LFSR 一直跑
错误!
工程标准:只有数据有效时才移位,否则扰码序列会错位,接收端解不出来。
坑 3:初相写错
必须全部 1:11111111
如果写全 0,LFSR 会卡死不动,永远输出 0。
坑 4:高低位搞反
多项式 x\^8 对应代码 reg7
多项式下标从 1 开始,代码下标从 0 开始,新手极易写错位。
十、设计总结
-
基于标准 8 阶 LFSR、453 多项式,完全匹配通信、视频传输工程需求
-
加扰解扰对称结构,极简、稳定、可直接工程移