#PCIE# pcie 中的scramber 和 de-scramber 技术

目录

0 老生常谈

1 加扰的目的

2 扰码器的分类

2.1 串行扰码器

2.2 并行扰码器

3 扰码电路设计要点

4 PCIe扰码电路

5 PCIe扰码器- Verilog RTL


0 老生常谈

原理:扰码器使用LFSR实现,用来产生伪随机比特序列,它和串行输入的数据进行异或,从而实现对输入数据的随机化。正如我们在LFSR部分讨论过的,伪随机序列也是周期重复的,其周期长度取决于LFSR中触发器的级数和所选择的多项式。接收电路本地有一个和发送电路中相同的伪随机序列产生器,它产生的数据与接收数据进行异或,可以恢复出发端原始的串行数据。

这里用到了一个逻辑运算表达式:如果A^B=C,那么C^B=A,此处A为原始数据,B为扰码器的输出,C为扰码后的数据。如图6.4所示:

1 加扰的目的

扰码有以下两个作用:

(1)扰码可以使重复的数据图案的频谱被展宽。例如,在数据流中重复出现序列10101010,这会导致高频离散频谱的出现从而产生较强的EMI(电磁干扰)。当进行扰码后,该数据被随机化,EMI噪声会大大减弱。

(2)扰码的另一用处是减少并行线路中的串扰。扰码可以使功率谱分布更为平滑和均匀,从而降低高频串扰。
 

2 扰码器的分类

2.1 串行扰码器


结合LFSR及其给出的多项式可以方便地设计串行扰码器。对于串行扰码器,一个时钟周期只有1比特的用户数据到达,每个时钟上升沿之后输出一位经过扰码后的数据,同时LFSR内部触发器的值被更新。然而,很多时候在一个时钟周期内到达多个比特的数据,此时我们需要设计并行扰码器,它可以在一个时钟周期内输入和输出多位数据。

2.2 并行扰码器


对并行数据加扰,遵循和串行加扰同样的算法。以每个时钟周期到达8位并行数据为例,LFSR伪随机序列产生器需要在每个时钟周期内产生8位随机数,同时扰码器在每个时钟周期内产生8位扰码后的随机数据。我们可以假定有一个8倍于当前并行数据工作时钟的虚拟时钟,在8个虚拟时钟周期之后,LFSR伪随机序列产生器可以产生8位数据(注意,LFSR伪随机序列产生器的输出与当前输入数据是无关的,与寄存器的当前状态有关),这8位数据与输入的8位原始数据进行异或,就可以得到并行扰码的最终结果。在后面的部分中,我们将对PCIe专用扰码器的实现进行讨论。并行扰码技术同样适用于16比特或32比特的并行数据。

OutputLogic.com

3 扰码电路设计要点

我们讨论了如何对串行数据及并行数据进行加扰处理,然而,为了实现扰码电路,还需要注意以下三个要点。

(1)扰码器初始化

发送电路和接收电路必须可以独立地对扰码器和解扰器进行初始化,否则二者就不能实现同步,从而接收电路也无法恢复出原始数据。PCIe中使用了一个名为COM的字符,发送电路和接收电路都可以识別该字符,并在收到该字符后将电路中的扰码器置为预先约定的相同的初始始值。这些COM字符被周期性地发送,使得收发双方能够同步或者对LFSR进行周期性的初始化。

(2)扰码器暂停

正常工作时,LFSR内部触发器的值在每个时钟周期都会进行更新,然而,LFSR应该可以被暂停更新。例如,在PCIe中,数据流中会添加或删除SKIP字符,并且SKIP字符的数量在中间处理过程中还可能发生变化。无论是发送电路还是接收电路,SKIP字符都是不需要进行扰码和解扰处理的,因此扰码电路和解扰电路应该可以在这些字符出现时进入“暂停”状态,“跳过”对它们的处理。

(3)扰码器去使能

扰码器还应该可以工作在LFSR内部寄存器不断更新,但不产生有效输出的状态。例如,在PCIe中,训练字符(TS1/TS2)未被加扰,但LFSR内部仍能不断更新。

4 PCIe扰码电路
 

PCIe扰码器(如图6.5所示)是一个16位LFSR多项式如下:

  • 它有16个LFSR触发器,图6.5是其具体电路;

  • COM字符将LFSR初始化为16’hFFFF;

  • SKP字符可以令其工作暂停。

PCIe扰码器工作波形如图6.6所示。

 5 PCIe扰码器- Verilog RTL

 // note : 每时钟周期处理8比特并行数据

module scrambler_8bits
  (clk,
  rstb,
  data_in,
  k_in,
  disab_scram,
  data_out,
  k_out);
 
//****************************************************************
input clk;
input rstb;
input [7:0]data_in; // input data to be scrambled
input k_in; // when 1, the input is a control character.
// when 0, the data is regular data
 
input disab_scram; // when 1 scrambling is disabled ,
output [7:0] data_out; // scrambled data output
output k_out; // when 1 the output is a control character.
 
//****************************************************************
localparam LFSR INIT = 16‘hFFFF;
 
reg  [15:0] lfsr, lfsr_nxt;
wire [15:0] lfsr_int;
wire initialize_scrambler, pause_scrambler;
reg  [7:0] data_out, data_out_nxt;
wire [7:0] data_out_int;
 
 
/* First find the equations for the LFSR flops. Since there are 8 bits of data coming input, the LFSR flops value moves 8 times (as there is an imaginary clock running 8 times faster). Find the intermediate value. Refer to PCIe sepe for the following algorithm */
 
assign lfsr_int[0]  = lfsr[8];
assign lfsr_int[l]  = lfsr[9];
assign Ifsr_int[2]  = lfsr[10];
assign lfsr_int[3]  = lfsr[8] ^ lfsr[ll];
assign lfsr_int[4]  = lfsr[8] ^ lfsr[9]  ^ lfsr[12];
assign lfsr_int[51  = lfsr[8] ^ lfsr[9]  ^ lfer[10] ^ lfsr[13];
assign lfsr_int[6]  = lfsr|9] ^ lfsr[10] ^ lfsr[l1] ^ lfsr[14];
assign lfsr_int[7]  = lfsr[10]^ lfsr[ll] ^ lfsr[12] ^ lfsr[15];
assign lfsr_inr[8]  = lfsr[0] ^ lfsr[l1] ^ lfsr[12] ^ lfsr[13];
assign lfsr_int[9]  = lfsr[l] ^ lfsr[12] ^ lfsr[13] ^ lfsr|14];
assign lfsr_int[10] = lfsr|2] ^ lfsr|13] ^ lfsr[14] ^ lfsr[15];
assign lfsr_int[l1] = lfsr[3] ^ lfsr[l4] ^ lfsr[15];
assign lfsr_int[l2] = lfsr[4] ^  lfsr[15];
assign lfsr_int[13] = lfsr[5];
assign lfsr_int[14] = lfsr[6];
assign lfsr_int[15] = lfsr[7];
 
// now use the special handles to define lfsr_nxt[15:0]
//****************************************************************
assign initialize_scrambler = (data_in == 8'hBC) && (k_in == 1); //COM char
assign pause_scrambler = (data_in == 8'h1C) && (k_in == 1) // SKP char
always @(*)
    begin
        lfsr_nxt = lfsr;
    if (disab_scram | pause_scrambler )
        lfsr_nxt = lfsr;
    else if (initialize_scrambler)
        lfsr_nxt = LFSR_INIT;
    else
        lfsr_nxt = lfsr_int;
    end
    
    
    // flop inference
    
always @(posedge clk or negedge rstb)
    begin
      if(!rstb)
        lfsr <= LFSR_INIT;
       else
        lfsr <= lfsr_nxt;
    end
// Now we need to perform the XOR operation with the input data_in to derive
// scrambled data First derive data_outjnt[7:0]
//****************************************************************
assign data_out_int[0] = data_in[0] ^ lfsr[l5];
assign data_out_int[1] = data_in[1] ^ lfsr[l4];
assign data_out_int[2] = data_in[2] ^ lfsr[13];
assign data_out_int[3] = data_in[3] ^ lfsr[12];
assign data_out_int[4] = data_in[4] ^ lfsr[l1];
assign data_out_int[5] = data_in[5] ^ lfsr[l0];
assign data_out_int[6| = data_in[6] ^ lfsr[9];
assign data_out_int[7] = data_in[7] ^ lfsr[8];
 
always @(*)
begin
  data_out_nxt = data_out_int;
  
  if (disab_scram || k_in) // scrambling disabled or input control character
        data_out_nxt = data_in;
  else
        data_out_nxt = data_out_int;
end
 
// flop inference
//****************************************************************
always @(posedge clk or negedge rstb)
begin
  if(!rstb)
      data_out <= 'd0;
  else
      data_out <= data_out_nxt;
end
endmodule

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值