The 8b8w Code

The codebook of the 8b8w chordal code consists of 256 judiciously chosen

The 8b8w code is used to transmit 8 bits on a collection of 8 wires in every UI. The codebook of the 8b8w chordal code consists of 256 judiciously chosen permutations of the vector (+1,+1,0,0,0,0,-1,-1). The encoder creates for any given byte two sets of bit masks of length 8. The first, called "plus" has a 1 in exactly those positions where the corresponding codeword has a +1, and zeros elsewhere. The second bit mask, called "minus" has a 1 in exactly those positions where the corresponding codeword has a -1. Accordingly, the Hamming weights of each of these bit masks is 2.

The following verilog code is one implementation of an encoder:

//
// 8-bit 8-wire encoder logic only (without flipflops).
//
module enc8b8w (
  input  [7:0] x,
  output [7:0] plus,
  output [7:0] minus);

  // Input is a 2-bit vector 'i'.
  // Output is a 4-bit vector with a single '1' on the index 'i'.
  function [3:0] one(input [1:0] i);
    begin
      case (i)
        2'b00   : one = 4'b0001;
        2'b01   : one = 4'b0010;
        2'b10   : one = 4'b0100;
        2'b11   : one = 4'b1000;
        default : one = 4'bxxxx;
      endcase
    end
  endfunction

  // Input is a 2-bit vector 'i'.
  // Output is a 4-bit vector with a '11' shifted to the left by 'i'
  // bits.
  function [3:0] two(input [1:0] i);
    begin
    case (i)
        2'b00   : two = 4'b0011;
        2'b01   : two = 4'b0110;
        2'b10   : two = 4'b1100;
        2'b11   : two = 4'b1001;
        default : two = 4'bxxxx;
      endcase
    end
  endfunction

  // Output is 16-bit vector with the lower 8-bit encoding
  // the minus positions and the top 8-bit encoding the
  // plus positions.
  function [15:0] encode8b8w(input [7:0] x);
    reg [1:0] a, b, c, d;
    reg [7:0] plus, minus;

    begin
      a = x[1:0];
      b = x[3:2];
      c = x[5:4];
      d = x[7:6];

      if (a==b)
        if (c==d)
          begin
            // two +1 in top half, two -1 in bottom half
            plus = {two(c) ,4'b0000};
            minus = {4'b0000, two(a)};
          end
        else
          begin
            // two -1 in top half, one +1 in bottom half, and one in top half
            plus = {one(d), one(b)};
            minus = {~(one(c) | one(d)), 4'b0000};
          end
      else
        if (c==d)
          begin
            // two -1 in bottom half, one +1 in bottom half, and one in top half
            plus = {one(c), one(b)};
            minus = {4'b0000, ~(one(a) | one(b))};
          end
        else
          begin
            // one +1 and one -1 in each half
            plus = {one(d), one(b)};
            minus = {one(c), one(a)};
          end

      encode8b8w = {plus, minus};
    end
  endfunction

  wire [15:0] pm;

  assign pm = encode8b8w(x);
  assign plus  = pm[15:8];
  assign minus = pm[7:0];

endmodule

The following is a possible driver for this code:

module driver;
  reg clk;

  reg [7:0] enc_x;
  wire [7:0] enc_plus;
  wire [7:0] enc_minus;

  enc8b8w enc(
              .x(enc_x),
              .plus(enc_plus),
              .minus(enc_minus));

  always
    #1 clk=~clk;
  initial
    begin: sweep_inputs
  integer i;
  clk =0'b0;
  for ( i = 0; i < 256; i = i+1 )
    begin
      @(posedge clk);
      enc_x=i;
      @(negedge clk);
      $display("%x   %x  %x",enc_x, enc_plus,enc_minus);
    end
  #10 $finish;
  end
endmodule // driver

Accordingly, the elements of this instantiation of the 8b8w code are as follows:

003003,01110c,02110a,031106,04120c,053006,061209,071205,
08140a,091409,0a300c,0b1403,0c1806,0d1805,0e1803,0f3009,
1011c0,111122,121124,131128,141221,1512c0,161224,171228,
181421,191422,1a14c0,1b1428,1c1821,1d1822,1e1824,1f18c0,
2011a0,211142,221144,231148,241241,2512a0,261244,271248,
281441,291442,2a14a0,2b1448,2c1841,2d1842,2e1844,2f18a0,
301160,311182,321184,331188,341281,351260,361284,371288,
381481,391482,3a1460,3b1488,3c1881,3d1882,3e1884,3f1860,
4021c0,412112,422114,432118,442211,4522c0,462214,472218,
482411,492412,4a24c0,4b2418,4c2811,4d2812,4e2814,4f28c0,
506003,51210c,52210a,532106,54220c,556006,562209,572205,
58240a,592409,5a600c,5b2403,5c2806,5d2805,5e2803,5f6009,
602190,612142,622144,632148,642241,652290,662244,672248,
682441,692442,6a2490,6b2448,6c2841,6d2842,6e2844,6f2890,
702150,712182,722184,732188,742281,752250,762284,772288,
782481,792482,7a2450,7b2488,7c2881,7d2882,7e2884,7f2850,
8041a0,814112,824114,834118,844211,8542a0,864214,874218,
884411,894412,8a44a0,8b4418,8c4811,8d4812,8e4814,8f48a0,
904190,914122,924124,934128,944221,954290,964224,974228,
984421,994422,9a4490,9b4428,9c4821,9d4822,9e4824,9f4890,
a0c003,a1410c,a2410a,a34106,a4420c,a5c006,a64209,a74205,
a8440a,a94409,aac00c,ab4403,ac4806,ad4805,ae4803,afc009,
b04130,b14182,b24184,b34188,b44281,b54230,b64284,b74288,
b84481,b94482,ba4430,bb4488,bc4881,bd4882,be4884,bf4830,
c08160,c18112,c28114,c38118,c48211,c58260,c68214,c78218,
c88411,c98412,ca8460,cb8418,cc8811,cd8812,ce8814,cf8860,
d08150,d18122,d28124,d38128,d48221,d58250,d68224,d78228,
d88421,d98422,da8450,db8428,dc8821,dd8822,de8824,df8850,
e08130,e18142,e28144,e38148,e48241,e58230,e68244,e78248,
e88441,e98442,ea8430,eb8448,ec8841,ed8842,ee8844,ef8830,
f09003,f1810c,f2810a,f38106,f4820c,f59006,f68209,f78205,
f8840a,f98409,fa900c,fb8403,fc8806,fd8805,fe8803,ff9009

In this representation, the first two hex-digits correspond to the input byte, the next two hex-digits correspond to the mask plus, and the last two hex-digits correspond to the mask minus.

The multi-input comparators used in our two prototypes we determine the positions of the wires with the two maximum and two minimum values. This is done with different low power, high speed, architectures. This information is tantamount to a codeword of the 8b8w-code. A digital decoder uses this codeword to determine a byte the encoding of which would be this codeword.