碎碎思 · 2021年09月09日

高速串行通信常用的编码方式-8b/10b编码/解码

绪论

8b/10b编码/解码是高速串行通信,如PCle SATA(串行ATA),以及Fiber Channel中常用的编解码方式。在发送端,编码电路将串行输入的8比特一组的数据转变成10比特一组的数据并输出;在接收端,解码器将10比特一组的输入数据转换成8比特一组的输出数据。编码和解码采用相同算法,整个过程就是8b/10b编码/解码过程。

这种编码方式的0-1、1-0跳变丰富,0和1分布均匀,不会出现长连0和长连1。例如,8b/10b编码比特流中连续出现的0或1的最大数量是5。这有助于为数据流提供DC平衡,可以为接收端时钟恢复提供足够的比特翻转(1-0,0-1)。在1983年,这种编码方式首次由IBM工程师奥尔•韦迪莫和皮特•弗兰斯科发明,之后IBM申请了发明专利。

8b/10b编码方式

进行8b/10b编码时,输入的每8比特数据转化为10比特数据,这10比特数据称为一个编码符号或编码字符,如图6.20所示。
image.png
编码时,将8比特数据分成两个子组,即低5位子组和高3位子组。低5位编码后为一个6比特值,高3位编码后为一个4比特值,此后将二者拼接,可以得到一个10比特字符。对于8比特输人,会有256种可能的组合,然而对于10比特,就会 有1024(1K)种组合,除了有过多连0和连1的编码组合被丢弃不用外,还要选择部分10比特组合作为控制字符,或者称为K字符。

这些特殊的控制符具有不同用途,例如,作为包的开始标识、包的结束标识,以及特殊COMMA符号。还有一些编码字符既不属于控制字符也不属于和256种8比特输入数据对应的编码字符,它们都是非法字符,正常工作时不会出现在编码比特字符流中。在数据传输出错时可能会出现非法字符。图6.20详细介绍了低5比特和高3比特转换成10比特编码字符的具体方式。

多字节8b/10b编码

在一些应用中,每个时钟周期需要对多字节进行编码。图6.21是对16比特数据进行8b/10b编码的一种实现方案,它可以在每个时钟周期进行两字节数据的8b/10b编码。

image.png

编码器1输岀的disparity信号被当成编码器2的disparity输入。两个编码器的编码和disparity计算在相同的时钟周期内进行。最终的disparity(编码器2的输出)经过一个寄存器后作为16比特数据的disparity,也就是当前运行的disparity,同时它还作为编码器1下一个时钟周期的disparity输入。

disparity选择8b/10b编码方案

当进行8b/10b编码的并行数据字节数增加时(例如,4字节),编码延迟会增大,从而使编码器不能满足高速工作时的定时要求。对于四级级联译码器来说,最后一级的disparity和10b编码结果的计算延迟最大。计算disparity的逻辑处于关键延迟路径上,只有等前面各级计算结束后才能计算组后一级的disparity值。改进定时特性,提高编码速度的一种重要方法是采用disparity选择机制。

图6.22给出了disparity选择编码电路的结构。对除第一级之外的每一级编码器,单独计算每一级的disparity值,包括一个正disparity值和一个负disparity值,最终的disparity值需要根据前一级的输出进行选择,由于选择器的延迟小于disparity计算逻辑,因此这种方法可以提高电路的工作速度。这种方案由于增加了disparity十算电路的数量,因此会消耗更多的逻辑电路资源。

image.png

代码举例

端口说明

## Encoder

### Ports

* `clk` - input Clock
* `rst` - input Reset (Active-HIGH)
* `en` - input Enable (Active-HIGH)
* `kin` - K- or D-symbol selection (`1 - K`, `0 - D`)
* `din` - 8-bit data input
* `dout` - 10-bit data output
* `disp` - Disparity flag output 
* `kin_err` - K-symbol error output

## Decoder

### Ports

* `clk` - input Clock
* `rst` - input Reset (Active-HIGH)
* `en` - input Enable (Active-HIGH)
* `din` - 10-bit data input
* `dout` - 8-bit data output
* `kout` - K- or D-symbol flag (`1 - K`, `0 - D`)
* `code_err` - Code error flag output
* `disp` - Disparity output
* `disp_err` - Disparity error flag output

decoder_8b10b.v

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Dmitry Matyunin (https://github.com/mcjtag)
// 
// Create Date: 06.04.2021 23:10:30
// Design Name: 
// Module Name: decoder_8b10b
// Project Name: v8b10b
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

module decoder_8b10b (
 input wire clk,
 input wire rst,
 input wire en,
 input wire [9:0]din,
 output wire [7:0]dout,
 output wire kout,
 output wire code_err,
 output wire disp,
 output wire disp_err
);
   
reg [7:0]do;
reg k;
reg ce;
reg [2:0]e;
reg p;
reg [3:0]pe;
wire [9:0]d;

assign d = din;
assign disp_err = pe?1'b1:1'b0;
assign dout = do;
assign kout = k;
assign code_err = ce;
assign disp = p;

always @(posedge clk) begin
 if (rst) begin
  k <= 0;
  do <= 8'b0; 
 end else begin
  if (en == 1'b1) begin
   k <= (((d[7]&d[6]&d[5]&d[4])|(!d[7]&!d[6]&!d[5]&!d[4]))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&(!d[5]&d[4]&d[2]&d[1]&d[0]))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&(d[5]&!d[4]&!d[2]&!d[1]&!d[0])));
   do[7] <= ((d[0]^d[1])&!((!d[3]&d[2]&!d[1]&d[0]&!(!(d[7]|d[6]|d[5]|d[4])))|(!d[3]&d[2]&d[1]&!d[0]&(!(d[7]|d[6]|d[5]|d[4])))|(d[3]&!d[2]&!d[1]&d[0]&!(!(d[7]|d[6]|d[5]|d[4])))|(d[3]&!d[2]&d[1]&!d[0]&(!(d[7]|d[6]|d[5]|d[4])))))|(!d[3]&d[2]&d[1]&d[0])|(d[3]&!d[2]&!d[1]&!d[0]);
   do[6] <= (d[0]&!d[3]&(d[1]|!d[2]|!(!(d[7]|d[6]|d[5]|d[4]))))|(d[3]&!d[0]&(!d[1]|d[2]|(!(d[7]|d[6]|d[5]|d[4]))))|(!(!(d[7]|d[6]|d[5]|d[4]))&d[2]&d[1])|((!(d[7]|d[6]|d[5]|d[4]))&!d[2]&!d[1]);
   do[5] <= (d[0]&!d[3]&(d[1]|!d[2]|(!(d[7]|d[6]|d[5]|d[4]))))|(d[3]&!d[0]&(!d[1]|d[2]|!(!(d[7]|d[6]|d[5]|d[4]))))|((!(d[7]|d[6]|d[5]|d[4]))&d[2]&d[1])|(!(!(d[7]|d[6]|d[5]|d[4]))&!d[2]&!d[1]);
   do[4] <= d[5]^(((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5])|(!d[7]&!d[6]&!d[5]&!d[4])|(!d[9]&!d[8]&!d[5]&!d[4]))|((((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[9]&!d[7]&(!(d[5]^d[4])))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6])) & !d[9] & !d[8]))&!d[4]))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&d[6]&d[5]&d[4])|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[8]&!d[7]&(!(d[5]^d[4])))));
   do[3] <= d[6]^(((d[9]&d[8]&d[5]&d[4])|(!d[7]&!d[6]&!d[5]&!d[4])|(((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&d[4]))|((((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[9]&d[7]&(!(d[5]^d[4])))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5]))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&d[6]&d[5]&d[4])|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[8]&!d[7]&(!(d[5]^d[4])))));
   do[2] <= d[7]^(((((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[9]&!d[7]&(!(d[5]^d[4])))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5]))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&d[4])|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[8]&d[7]&(!(d[5]^d[4])))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&d[6]&d[5]&d[4]))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5])|(!d[7]&!d[6]&!d[5]&!d[4])|(!d[9]&!d[8]&!d[5]&!d[4])));
   do[1] <= d[8]^(((d[9]&d[8]&d[5]&d[4])|(!d[7]&!d[6]&!d[5]&!d[4])|(((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&d[4]))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&d[4])|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[8]&d[7]&(!(d[5]^d[4])))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&d[6]&d[5]&d[4]))|((((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[9]&d[7]&(!(d[5]^d[4])))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5])));
   do[0] <= d[9]^(((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&d[6]&d[5]&d[4])|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[8]&!d[7]&(!(d[5]^d[4]))))|((((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[9]&!d[7]&(!(d[5]^d[4])))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5]))|((d[9]&d[8]&d[5]&d[4])|(!d[7]&!d[6]&!d[5]&!d[4])|(((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&d[4])));
  end
 end
end
   
always @(posedge clk) begin
 if (rst) begin
  p <= 1'b0;
  pe <= 4'hF;
  ce <= 1'b1;
  e = 3'b000;
 end else begin
  if (en == 1'b1) begin
   p <= (((!((d[3]&d[2])|(!d[3]&!d[2])))&d[1]&d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&d[3]&d[2]))|(((d[5]&d[4]&!(((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!p))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&p))&(d[5]|d[4]))|(((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&p))&((d[3]&d[2]&!d[1]&!d[0])|(!d[3]&!d[2]&d[1]&d[0])|(!((d[3]&d[2])|(!d[3]&!d[2]))&!((d[1]&d[0])|(!d[1]&!d[0]))))) ;
   pe[0] <= ((p&((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&(d[5]|d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[5]&d[4])))|(((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!(d[5]&d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[5]&!d[4]))&!p))|((p&!((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!(d[5]&d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[5]&!d[4]))&d[3]&d[2]));
   pe[1] <= ((p&d[9]&d[8]&d[7]))|((p&!((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!(d[5]&d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[5]&!d[4]))&(((!((d[3]&d[2])|(!d[3]&!d[2])))&d[1]&d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&d[3]&d[2]))));
   pe[2] <= ((!p&!((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&(d[5]|d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[5]&d[4]))&!d[3]&!d[2]))|((!p&!d[9]&!d[8]&!d[7]));
   pe[3] <= ((!p&!((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&(d[5]|d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[5]&d[4]))&((!((d[3]&d[2])|(!d[3]&!d[2]))&!d[1]&!d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&!d[3]&!d[2]))))|((((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&(d[5]|d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[5]&d[4]))&(((!((d[3]&d[2])|(!d[3]&!d[2])))&d[1]&d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&d[3]&d[2])))|(((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!(d[5]&d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[5]&!d[4]))&((!((d[3]&d[2])|(!d[3]&!d[2]))&!d[1]&!d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&!d[3]&!d[2]))));
   e[0] <= ((d[9]&d[8]&d[7]&d[6])|(!d[9]&!d[8]&!d[7]&!d[6]))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5]&!d[4]))|((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&d[5]&d[4]))|((d[3]&d[2]&d[1]&d[0])|(!d[3]&!d[2]&!d[1]&!d[0]))|((d[5]&d[4]&d[3]&d[2]&d[1])|(!d[5]&!d[4]&!d[3]&!d[2]&!d[1]))|((d[5]&!d[4]&d[2]&d[1]&d[0])|(!d[5]&d[4]&!d[2]&!d[1]&!d[0]))|((((d[5]&d[4]&!d[2]&!d[1]&!d[0])|(!d[5]&!d[4]&d[2]&d[1]&d[0]))&!((d[7]&d[6]&d[5])|(!d[7]&!d[6]&!d[5]))))|((!((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&d[5]&!d[4]&!d[2]&!d[1]&!d[0]))|((!((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!d[5]&d[4]&d[2]&d[1]&d[0]));
   e[1] <= ((((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&(d[5]|d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[5]&d[4]))&(((!((d[3]&d[2])|(!d[3]&!d[2])))&d[1]&d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&d[3]&d[2])))|(((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!(d[5]&d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[5]&!d[4]))&((!((d[3]&d[2])|(!d[3]&!d[2]))&!d[1]&!d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&!d[3]&!d[2]))))|((d[3]&d[2]&!d[1]&!d[0]&((((!((d[9]&d[8])|(!d[9]&!d[8]))&d[7]&d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&d[9]&d[8]))&(d[5]|d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&d[5]&d[4]))))|((!d[3]&!d[2]&d[1]&d[0]&((((!((d[9]&d[8])|(!d[9]&!d[8]))&!d[7]&!d[6])|(!((d[7]&d[6])|(!d[7]&!d[6]))&!d[9]&!d[8]))&!(d[5]&d[4]))|(((d[9]&d[8]&!d[7]&!d[6])|(d[7]&d[6]&!d[9]&!d[8])|(!((d[9]&d[8])|(!d[9]&!d[8]))&!((d[7]&d[6])|(!d[7]&!d[6]))))&!d[5]&!d[4]))));
   e[2] <= ((d[9]&d[8]&d[7]&!d[5]&!d[4]&((!d[3]&!d[2])|((!((d[3]&d[2])|(!d[3]&!d[2]))&!d[1]&!d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&!d[3]&!d[2])))))|((!d[9]&!d[8]&!d[7]&d[5]&d[4]&((d[3]&d[2])|(((!((d[3]&d[2])|(!d[3]&!d[2])))&d[1]&d[0])|(!((d[1]&d[0])|(!d[1]&!d[0]))&d[3]&d[2])))))|((d[7]&d[6]&d[5]&d[4]&!d[3]&!d[2]&!d[1]))|((!d[7]&!d[6]&!d[5]&!d[4]&d[3]&d[2]&d[1]));
   ce <= e ? 1'b1 : 1'b0;
  end
 end
end

endmodule

encoder_8b10.v

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Dmitry Matyunin (https://github.com/mcjtag)
// 
// Create Date: 06.04.2021 23:11:28
// Design Name: 
// Module Name: encoder_8b10
// Project Name: v8b10b
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

module encoder_8b10
(
 input wire clk,
 input wire rst,
 input wire en,
 input wire kin,
 input wire [7:0]din,
 output wire [9:0]dout,
 output wire disp,
 output wire kin_err
);

reg p;
reg ke;
reg [18:0]t;
reg [9:0]do;
wire [7:0]d;
wire k;

assign d = din;
assign k = kin;

assign dout = do;
assign disp = p;
assign kin_err = ke;

always @(posedge clk) begin
 if (rst) begin
  p <= 1'b0;
  ke <= 1'b0;
  do <= 10'b0;
 end else begin
  if (en == 1'b1) begin
   p <= ((d[5]&d[6]&d[7])|(!d[5]&!d[6]))^(p^(((d[4]&d[3]&!d[2]&!d[1]&!d[0])|(!d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&d[2]&d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&d[0]&d[1]))))|(k|(d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&!d[2]&!d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&!d[0]&!d[1]))))));
   ke <= (k&(d[0]|d[1]|!d[2]|!d[3]|!d[4])&(!d[5]|!d[6]|!d[7]|!d[4]|!((!((d[0]&d[1])|(!d[0]&!d[1]))&d[2]&d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&d[0]&d[1])))); 
   do[9] <= t[12]^t[0];
   do[8] <= t[12]^(t[1]|t[2]);
   do[7] <= t[12]^(t[3]|t[4]);
   do[6] <= t[12]^t[5];
   do[5] <= t[12]^(t[6]&t[7]);
   do[4] <= t[12]^(t[8]|t[9]|t[10]|t[11]);
   do[3] <= t[13]^(t[15]&!t[14]);
   do[2] <= t[13]^t[16];
   do[1] <= t[13]^t[17];
   do[0] <= t[13]^(t[18]|t[14]);
  end
 end
end
  
always @(posedge clk) begin
 if(rst) begin
  t <= 0;
 end else begin
  if (en == 1'b1) begin
   t[0] <= d[0];
   t[1] <= d[1]&!(d[0]&d[1]&d[2]&d[3]);
   t[2] <= (!d[0]&!d[1]&!d[2]&!d[3]);
   t[3] <= (!d[0]&!d[1]&!d[2]&!d[3])|d[2];
   t[4] <= d[4]&d[3]&!d[2]&!d[1]&!d[0];
   t[5] <= d[3]&!(d[0]&d[1]&d[2]);
   t[6] <= d[4]|((!((d[0]&d[1])|(!d[0]&!d[1]))&!d[2]&!d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&!d[0]&!d[1]));
   t[7] <= !(d[4]&d[3]&!d[2]&!d[1]&!d[0]);
   t[8] <= (((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!d[4])|(d[4]&(d[0]&d[1]&d[2]&d[3]));
   t[9] <= d[4]&!d[3]&!d[2]&!(d[0]&d[1]);
   t[10] <= k&d[4]&d[3]&d[2]&!d[1]&!d[0];
   t[11] <= d[4]&!d[3]&d[2]&!d[1]&!d[0];
   t[12] <= (((d[4]&d[3]&!d[2]&!d[1]&!d[0])|(!d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&d[2]&d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&d[0]&d[1]))))&!p)|((k|(d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&!d[2]&!d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&!d[0]&!d[1])))|(!d[4]&!d[3]&d[2]&d[1]&d[0]))&p);
   t[13] <= (((!d[5]&!d[6])|(k&((d[5]&!d[6])|(!d[5]&d[6]))))&!(p^(((d[4]&d[3]&!d[2]&!d[1]&!d[0])|(!d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&d[2]&d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&d[0]&d[1]))))|(k|(d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&!d[2]&!d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&!d[0]&!d[1])))))))|((d[5]&d[6])&(p^(((d[4]&d[3]&!d[2]&!d[1]&!d[0])|(!d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&d[2]&d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&d[0]&d[1]))))|(k|(d[4]&!((d[0]&d[1]&!d[2]&!d[3])|(d[2]&d[3]&!d[0]&!d[1])|(!((d[0]&d[1])|(!d[0]&!d[1]))&!((d[2]&d[3])|(!d[2]&!d[3]))))&!((!((d[0]&d[1])|(!d[0]&!d[1]))&!d[2]&!d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&!d[0]&!d[1])))))));
   t[14] <= d[5]&d[6]&d[7]&(k|(p?(!d[4]&d[3]&((!((d[0]&d[1])|(!d[0]&!d[1]))&d[2]&d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&d[0]&d[1]))):(d[4]&!d[3]&((!((d[0]&d[1])|(!d[0]&!d[1]))&!d[2]&!d[3])|(!((d[2]&d[3])|(!d[2]&!d[3]))&!d[0]&!d[1])))));
   t[15] <= d[5];
   t[16] <= d[6]|(!d[5]&!d[6]&!d[7]);
   t[17] <= d[7];
   t[18] <= !d[7]&(d[6]^d[5]);
  end
 end
end

endmodule

VHDL文件详见:https://github.com/suisuisi/8b10b\_encdec

其他常用编码方式

8b/10b编码为时钟恢复提供了足够的0与1翻转,但编码效率较低,每传输10比特数据,只有8比特为有效数据,编码效率只有80%,有20%为辅助比特。64b/66b编码中的0、1分布不如8b/10b均匀,但编码效率高,辅助比特少,每66比特中只有2比特是辅助比特,所占比例仅为3%。64b/66b被用于10Gbit以太网中。本部分将详细介绍64b/66b编码。

64b/66b编码机制

66比特的编码块由2比特的前导码和64比特数据组成。

  • 当前导码为“01”时,后面的64比特为数据;
  • 当前导码为“10”时,其后的8比特为类型字段,后56比特为数据;
  • 其他两个值“11”和“00”未被使用。

前导码(10和01)可以保证每66比特中至少有一次比特翻转,可用于时钟恢复。与64b/66b编码电路相连的还有一个扰码电路。

128b/130b编码机制

128b/130b编码用于PCIe Gen3以取代8b/l0b编码/解码。8b/10b编码中除了数据编码字符外还有很多控制字符,用于表示包的开始始、包的结束等。然而,该编码方式编码效率较低,辅助比特占了20%。128b/130b编码中辅助比特很少(约为1.5%)。128比特的数据块加上2比特的同步头就可以构成一个130比特的编码块。同步头编码为2‘b01时表示后面跟随的是训练顺序组(training ordered set),2b'10表示后面的是数据(TLP、DLLP及空闲数据),2’bl1和2’b00被保留。由于128b/130b编码体制中没有额外的控制字符,因此需要使用其他机制来指出包的开始和结束。

原文:FPGA 的逻辑
作者:碎碎思

相关文章推荐

更多FPGA技术干货请关注FPGA 的逻辑技术专栏。
推荐阅读
关注数
10605
内容数
562
FPGA Logic 二三事
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息