Verilog数字系统基础设计-扰码与解扰

本文介绍了数字系统设计中扰码与解扰的概念,扰码通过LFSR生成伪随机序列与数据异或,用于数据随机化,减少EMI和串扰。文中详细阐述了串行和并行扰码器的设计,以及PCIe专用扰码器的工作原理,并提供了Verilog代码示例实现8位并行扰码器。重点强调了扰码器初始化、暂停和去使能等设计要点。
摘要由CSDN通过智能技术生成

Verilog数字系统基础设计-扰码与解扰

扰码可以对原始的用户数据进行扰乱,得到随机化的用户数据。发送电路在发送数据前先对数据进行随机扰乱,接收电路使用相同的扰乱算法重新恢复出原始的数据。

什么是扰码与解扰

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

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

扰码的作用

扰码有以下两个作用:

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

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

串行扰码器

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

并行扰码器

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

扰码电路设计要点

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

(1)扰码器初始化

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

(2)扰码器暂停

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

(3)扰码器去使能

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

PCIe扰码电路

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

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

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

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

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

Verilog RTL-PCIe扰码器

// 每时钟周期处理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

学习Xilinx FPGA最好的资料其实就是官方手册,下表总结了部分手册的主要介绍内容,关注我,持续更新中......

Verilog数字系统基础设计-LFSR

推荐阅读

【Vivado那些事】如何查找官网例程及如何使用官网例程

【Vivado使用误区与进阶】总结篇

【Vivado那些事】Vivado中常用的快捷键(二)其他常用快捷键

SystemVerilog数字系统设计_夏宇闻 PDF

图书推荐|ARM Cortex-M0 全可编程SoC原理及实现

简谈:如何学习FPGA

1202年了,还在使用虚拟机吗?Win10安装Ubuntu子系统及图形化界面详细教程

Github 上有哪些优秀的 VHDL/Verilog/FPGA 项目

AD936x+ZYNQ搭建收音机(一)

AD936x+ZYNQ搭建OpenWIFI

无招胜有招-Vivado非工程模式下的详细设计

追寻ARM的起源-Acorn电脑简史及FPGA实现

面试中经常会遇到的FPGA基本概念,你会几个?

Xilinx FPGA MIPI 接口简单说明

介绍一些新手入门FPGA的优秀网站

Vivado ML(机器学习) 2021尝鲜

推荐一些可以获取免费的国外的原版书籍(电子版)网站

【Vivado那些事】FPGA的配置方式

FPGA 的重构

浅析FPGA局部动态可重构技术

ISP(图像信号处理)算法概述、工作原理、架构、处理流程

国产CPU概括

从电子游戏历史看IC发展的助推剂

80年代电子游戏及电脑游戏的发展历史

PCIe总线的基础知识

万字长文带你回顾电子游戏的七十多年历史(完整版)

FPGA中异步复位,同步释放的理解

OpenFPGA系列文章总结

用Verilog设计一个16 位 RISC 处理器

介绍一些新手入门FPGA的优秀网站(新增)

Verilog数字系统基础设计-CRC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OpenFPGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值