head 1.6;
access;
symbols;
locks; strict;
comment @# @;
1.6
date 2001.11.29.09.22.08; author bbeaver; state Exp;
branches;
next 1.5;
1.5
date 2001.10.26.10.32.13; author bbeaver; state Exp;
branches;
next 1.4;
1.4
date 2001.10.25.11.25.33; author bbeaver; state Exp;
branches;
next 1.3;
1.3
date 2001.10.25.07.52.00; author bbeaver; state Exp;
branches;
next 1.2;
1.2
date 2001.10.23.10.27.18; author bbeaver; state Exp;
branches;
next 1.1;
1.1
date 2001.10.22.12.29.08; author bbeaver; state Exp;
branches;
next ;
desc
@@
1.6
log
@no message
@
text
@//////////////////////////////////////////////////////////////////////
//// ////
//// encode_8b_10b #(N), decode_10b_8b #(N) ////
//// ////
//// This file is part of the general opencores effort. ////
//// ////
//// ////
//// Module Description: ////
//// Example of how to convert 8B data to 10B data. ////
//// Example of how to convert 10B data to 8B data. ////
//// ////
//// NOTE: ////
//// The IBM Patent grew up in a world where the Least ////
//// Significant Bit of a word was written to the Left. ////
//// These modules use the LSB as Bit 0, and it will ////
//// typically be written as the Rightmost bit in a field. ////
//// ////
//// NOTE: ////
//// These modules are based on information contained in ////
//// "Implementing an 8B/10B Encoder/Decoder for Gigabit ////
//// Ethernet" by Daniel Elftmann and Jing Hua Ma of Altera. ////
//// The paper was given in the International IC Tiapei ////
//// conferance in 1999. ////
//// ////
//// A second source of information is XAPP336 titled "Design ////
//// of a 16B/20B Encoder/Decoder using a Coolrunner CPLD" ////
//// found on the Xilinx web sire www.xilinx.com ////
//// ////
//// The best article describing this is at wildpackets.com ////
//// http://www.wildpackets.com/compendium/GB/L1-GbEn.html ////
//// ////
//// Finally, this is covered in US patent 4,665,517. ////
//// Unfortunately the US Patent Office online copy has ////
//// missing figures and the tables are un-readable. ////
//// ////
//// Author(s): ////
//// - Anonymous ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Anonymous and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// $Id: encode_8b_10b.v,v 1.19 2001/11/29 09:31:11 Blue Beaver Exp $
//
// CVS Revision History
//
// $Log: encode_8b_10b.v,v $
// Revision 1.19 2001/11/29 09:31:11 Blue Beaver
// no message
//
// Revision 1.18 2001/10/26 10:39:43 Blue Beaver
// no message
//
// Revision 1.17 2001/10/26 10:38:05 Blue Beaver
// no message
//
// Revision 1.16 2001/10/25 11:43:03 Blue Beaver
// no message
//
// Revision 1.14 2001/10/25 11:33:51 Blue Beaver
// no message
//
// Revision 1.13 2001/10/24 11:38:02 Blue Beaver
// no message
//
// Revision 1.12 2001/10/24 09:47:40 Blue Beaver
// no message
//
// Revision 1.11 2001/10/24 08:49:02 Blue Beaver
// no message
//
// Revision 1.10 2001/10/24 07:28:08 Blue Beaver
// no message
//
// Revision 1.9 2001/10/23 10:34:50 Blue Beaver
// no message
//
// Revision 1.8 2001/10/23 08:12:37 Blue Beaver
// no message
//
// Revision 1.7 2001/10/22 12:36:12 Blue Beaver
// no message
//
// Revision 1.6 2001/10/22 11:54:58 Blue Beaver
// no message
//
// Revision 1.5 2001/10/21 11:37:28 Blue Beaver
// no message
//
// Revision 1.4 2001/10/21 10:17:34 Blue Beaver
// no message
//
// Revision 1.3 2001/10/21 03:40:52 Blue Beaver
// no message
//
// Revision 1.2 2001/10/21 02:27:39 Blue Beaver
// no message
//
// Revision 1.1 2001/10/21 01:36:14 Blue Beaver
// no message
//
//
//
`timescale 1ns/1ps
// These are the codes which are valid to use as control codes.
// I believe that they have names, but I don't know them.
// Note K_28_1, K_28_5, and K_28_7 contain Singular Commas.
`define K_28_0 8'b000_11100
`define K_28_1 8'b001_11100
`define K_28_2 8'b010_11100
`define K_28_3 8'b011_11100
`define K_28_4 8'b100_11100
`define K_28_5 8'b101_11100
`define K_28_6 8'b110_11100
`define K_28_7 8'b111_11100
`define K_23_7 8'b111_10111
`define K_27_7 8'b111_11011
`define K_29_7 8'b111_11101
`define K_30_7 8'b111_11110
// Convert 8-bit binary or 8-bit control code to 10-bit code
module encode_8b_10b (
eight_bit_data_or_control_in,
input_is_control,
mess_up_link_disparity,
ten_bit_encoded_data_out,
invalid_control,
clk,
reset
);
input [7:0] eight_bit_data_or_control_in;
input input_is_control;
input mess_up_link_disparity;
output [9:0] ten_bit_encoded_data_out;
output invalid_control;
input clk, reset;
// Data is treated as 2 fields. The 3 MSB bits are treated as 1 field, and
// the 5 LSB bits are treated as another field.
// The 5 LSB bits are encoded as 6 bits. The 3 MSB bits are encoded as 4 bits.
// The encodings are chosen so that the 10 bits together have either
// 1) 5 1's and 5 0's,
// 2) 4 1's and 6 0's,
// 3 6 1's and 4 0's
// There are alternative encodings for the cases that the number of 1's and 0's
// are not balanced. The 8B/10B encoder keeps track of the running disparity
// between the number of 1's and 0's, and uses alternate encodings to keep
// the serial signal balanced with no disparity on average.
//
// TABLE I 5B/6B ENCODING (NOTE LSB TO LEFT)
// NAME ABCDE K D-1 abcdei DO ALTERNATE
// ______________________________________
// D.0 00000 0 + 011000 - 100111
// D.1 10000 0 + 100010 - 011101 !
// D.2 01000 0 + 010010 - 101101 !
// D.3 11000 0 x 110001 0 !
// D.4 00100 0 + 001010 - 110101 !
// D.5 10100 0 x 101001 0 !
// D.6 01100 0 x 011001 0 !
// D.7 11100 0 - 111000 0 000111 !
// D.8 00010 0 + 000110 - 111001 !
// D.9 10010 0 x 100101 0 !
// D.10 01010 0 x 010101 0 !
// D.11 11010 0 x 110100 0 !
// D.12 00110 0 x 001101 0 !
// D.13 10110 0 x 101100 0 !
// D.14 01110 0 x 011100 0 !
// D.15 11110 0 + 101000 - 010111
// D.16 00001 0 - 011011 + 100100
// D.17 10001 0 x 100011 0 !
// D.18 01001 0 x 010011 0 !
// D.19 11001 0 x 110010 0 !
// D.20 00101 0 x 001011 0 !
// D.21 10101 0 x 101010 0 !
// D.22 01101 0 x 011010 0 !
// D.23 11101 x - 111010 + 000101 !
// D.24 00011 0 + 001100 - 110011
// D.25 10011 0 x 100110 0 !
// D.26 01011 0 x 010110 0 !
// D.27 11011 x - 110110 + 001001 !
// D.28 00111 0 x 001110 0 !
// D.29 10111 x - 101110 + 010001 !
// D.30 01111 x - 011110 + 100001 !
// D.31 11111 0 - 101011 + 010100
//
// K.23 11101 x - 111010 + 000101 !
// K.27 11011 x - 110110 + 001001 !
// K.28 00111 1 - 001111 + 110000 !
// K.29 10111 x - 101110 + 010001 !
// K.30 01111 x - 011110 + 100001 !
//
// TABLE II 3B/4B ENCODING (NOTE LSB TO LEFT)
// NAME FGH K D-1 fghj DO ALTERNATE
// ______________________________________
// D.x.0 000 x + 0100 - 1011
// D.x.1 100 0 x 1001 0 !
// D.x.2 010 0 x 0101 0 !
// D.x.3 110 x - 1100 0 0011 !
// D.x.4 001 x + 0010 - 1101 !
// D.x.5 101 0 x 1010 0 !
// D.x.6 011 0 x 0110 0 !
// D.x.P7 111 0 - 1110 + 0001 ! Primary
// D.x.A7 111 x - 0111 + 1000 Alternate
//
// K.28.0 000 x + 0100 - 1011
// K.28.1 100 1 + 1001 0 0110 ! Singular Comma
// K.28.2 010 1 + 0101 0 1010 !
// K.28.3 110 x - 1100 0 0011 !
// K.28.4 001 x + 0010 - 1101 !
// K.28.5 101 1 + 1010 0 0101 ! Singular Comma
// K.28.6 011 1 + 0110 0 1001 !
// K.28.7 111 x - 0111 + 1000 Singular Comma
//
// K.23.7 111 x - 0111 + 1000
// K.27.7 111 x - 0111 + 1000
// K.29.7 111 x - 0111 + 1000
// K.30.7 111 x - 0111 + 1000
//
// The alternate Data encoding D.x.A7 is used in the case
// that e = i = 1 and negative running disparity,
// or e = i = 0 and positive running disparity,
// or a Control signal is being sent,
// all while encoding 7 in the MSB.
//
// This exception to the simple rule guarantees that there
// aren't a run of 5 1's or 5 0's in the first 6 bits
// concatinated with the last 4 bits.
//
// The special sequence starting at "a" of 2 0's followed by
// 5 1's, or 2 1's followed by 5 0's, is called a
// "Singular Comma".
// A Singular Comma does not occur in any valid code EXCEPT
// K.28.1 or K.28.5 or K.28.7.
//
// The web says K.28.5 is the Fiber Channel Comma Character.
//
// NOTE that K.28.7 is a bad comma character, because it
// can be followed by a FALSE comma character when followed
// by any character starting with 2 1's or 0's, like K.11
// The false comma character is part in the K.28.7 and part
// in the following data byte. Bad.
//
// The following info is found in www.wildpackets.com/compendium/GB/L1-GbEn.html,
// in a document headed:
// "Gigabit Ethernet is Closely Related to Fibre Channel Technology,
// going back to 1988!"
//
// 8B-10B characters are described as Dn.m, where n gives the low order
// 5 bits in decimal, and m gives the top 3 bits.
//
// Configuration data is transferred as an alternating sequence of:
// (flips disparity: "C1") K28.5/D21.5/Config_reg[7:0]/Config_reg[15:8]
// (leaves disparity: "C2") K28.5/D2.2/Config_reg[7:0]/Config_reg[15:8]
//
// Idle status is transmitted when ther eis nothing else to send.
// The link is left in negative disparity. If it is positive, first
// "I1" K28.5/D5.6 is sent, which knocks the displarity to negative
// "I2" K28.5/D16.2 is sent repeatitively to maintain the negative disparity
//
// Start of Packet delimiter "S" K27.7
// End of Packet delimiter "T" K29.7
// Carrier Extend "R" K23.7
//
// An End Of Packet consists of either T/R/I or T/R/R
// The second is used when a packet follows the previous packet in a burst.
// "R" is also sent so that a subsequent "I" follows on an even-numbered
// code boundry.
//
// Error propagation "V" K30.7
// Accumulate the new data. First, calculate ignoring the running disparity;
wire [9:0] first_level_encoded_data;
// Calculate the values for the 5 -> 6 encoding
// Discover important details about the incoming numbers.
wire [1:0] LSB_02_Population = eight_bit_data_or_control_in[0] // half adder
+ eight_bit_data_or_control_in[1];
wire [1:0] LSB_34_Population = eight_bit_data_or_control_in[2] // half adder
+ eight_bit_data_or_control_in[3];
wire [2:0] LSB_Population = {1'b0, LSB_02_Population[1:0]}
+ {1'b0, LSB_34_Population[1:0]};
// As can be seen, in many of the LSB encodings the bottom
// 4 of the encoded data are identical to the input
// data. (These are noted with a trailing "!")
//
// There are several exceptions to this in the LSB. Decode these.
wire LSB_all_zero = (LSB_Population[2:0] == 3'h0);
wire LSB_contains_one_one = (LSB_Population[2:0] == 3'h1);
wire LSB_contains_two_ones = (LSB_Population[2:0] == 3'h2);
wire LSB_contains_three_ones = (LSB_Population[2:0] == 3'h3);
wire LSB_all_one = (LSB_Population[2:0] == 3'h4);
wire LSB_is_7 = (eight_bit_data_or_control_in[4:0] == 5'h07); // 7
wire LSB_is_24 = (eight_bit_data_or_control_in[4:0] == 5'h18); // 24
wire LSB_is_28 = (eight_bit_data_or_control_in[4:0] == 5'h1C); // 28
wire LSB_is_23_27_29_30 = (eight_bit_data_or_control_in[4:0] == 5'h17) // 23
| (eight_bit_data_or_control_in[4:0] == 5'h1B) // 27
| (eight_bit_data_or_control_in[4:0] == 5'h1D) // 29
| (eight_bit_data_or_control_in[4:0] == 5'h1E); // 30
wire LSB_contains_other_i = (eight_bit_data_or_control_in[3:0] == 4'h0)
| (eight_bit_data_or_control_in[3:0] == 4'h1)
| (eight_bit_data_or_control_in[3:0] == 4'h2)
| (eight_bit_data_or_control_in[3:0] == 4'h4);
// Notice that the bottom bit of the encoded LSB data is the same as
// the input LSB data.
assign first_level_encoded_data[0] = eight_bit_data_or_control_in[0];
// If the bottom 4 bits are 0s, force 0110 (LSB is the left bit)
// If the bottom 5 bits are 24, force 0011 (LSB is the left bit)
// If the bottom 4 bits are 1s, force 1010 (LSB is the left bit)
assign first_level_encoded_data[1] = ( eight_bit_data_or_control_in[1]
& ~LSB_all_one)
| LSB_all_zero;
assign first_level_encoded_data[2] = eight_bit_data_or_control_in[2]
| LSB_all_zero
| LSB_is_24;
assign first_level_encoded_data[3] = ( eight_bit_data_or_control_in[3]
& ~LSB_all_one);
// Bits "e" and "i" are chosen to guarantee that there are enough transitions,
// and to control the disparity caused by each pattern.
assign first_level_encoded_data[4] =
(LSB_contains_one_one | eight_bit_data_or_control_in[4])
& ~LSB_is_24;
assign first_level_encoded_data[5] =
(LSB_contains_two_ones & ~eight_bit_data_or_control_in[4])
| ( ( LSB_contains_other_i | LSB_all_one)
& eight_bit_data_or_control_in[4])
| (input_is_control & LSB_is_28);
// Now calculate the other information needed to produce the LSB output data
wire LSB_code_has_positive_disparity =
| ( ( LSB_all_zero
| LSB_contains_three_ones
| LSB_all_one)
& (eight_bit_data_or_control_in[4] == 1'b1) )
| (input_is_control & LSB_is_28);
wire LSB_code_has_negative_disparity =
( ( LSB_all_zero
| LSB_contains_one_one
| LSB_all_one)
& (eight_bit_data_or_control_in[4] == 1'b0) )
| LSB_is_24;
wire invert_LSB_if_input_disparity_is_positive =
LSB_code_has_positive_disparity
| LSB_is_7;
wire invert_LSB_if_input_disparity_is_negative =
LSB_code_has_negative_disparity;
wire LSB_toggle_running_disparity =
LSB_code_has_positive_disparity
| LSB_code_has_negative_disparity;
// Calculate the values for the 3 -> 4 encoding
// An alternate encoding of the MSB for an input of 0x7 is used to
// prevent accidental use of a pattern with 5 0's or 1's in a row.
// The alternate Data encoding D.x.A7 is used in the case
// that e = i = 0 and positive running disparity,
// or e = i = 1 and negative running disparity,
// or a Control signal is being sent,
// all while encoding 7 in the MSB.
reg Running_Disparity; // forward reference
wire use_alternate_encoding =
( input_is_control
| ( (Running_Disparity == 1'b0)
& ( (eight_bit_data_or_control_in[4:0] == 5'h11) // 17
| (eight_bit_data_or_control_in[4:0] == 5'h12) // 18
| (eight_bit_data_or_control_in[4:0] == 5'h14) // 20
))
| ( (Running_Disparity == 1'b1)
& ( (eight_bit_data_or_control_in[4:0] == 5'h0B) // 11
| (eight_bit_data_or_control_in[4:0] == 5'h0D) // 13
| (eight_bit_data_or_control_in[4:0] == 5'h0E) // 14
))
)
& (eight_bit_data_or_control_in[7:5] == 3'h7);
// The low bit of the MSB is a pass-through, except when the alternate
// encoding of the value is used to prevent unintentional long runs.
assign first_level_encoded_data[6] = eight_bit_data_or_control_in[5]
& ~use_alternate_encoding;
// The second bit of the MSB is a pass-through except when the input
// is all 0's.
assign first_level_encoded_data[7] = eight_bit_data_or_control_in[6]
| (eight_bit_data_or_control_in[7:5] == 3'h0);
// The top bit of the encoded MSB data is the same as the input MSB data.
assign first_level_encoded_data[8] = eight_bit_data_or_control_in[7];
// Bit "j" is chosen to guarantee that there are enough transitions,
// and to control the disparity caused by each pattern.
assign first_level_encoded_data[9] =
(eight_bit_data_or_control_in[7:5] == 3'h1)
| (eight_bit_data_or_control_in[7:5] == 3'h2)
| use_alternate_encoding;
// Now calculate the other information needed to produce the MSB output data
wire invert_MSB_if_LSB_disparity_is_positive =
(eight_bit_data_or_control_in[7:5] == 3'h3)
| (eight_bit_data_or_control_in[7:5] == 3'h7);
wire invert_MSB_if_LSB_disparity_is_negative =
(eight_bit_data_or_control_in[7:5] == 3'h0)
| (eight_bit_data_or_control_in[7:5] == 3'h4)
| ( input_is_control
& ( (eight_bit_data_or_control_in[7:5] == 3'h1)
| (eight_bit_data_or_control_in[7:5] == 3'h2)
| (eight_bit_data_or_control_in[7:5] == 3'h5)
| (eight_bit_data_or_control_in[7:5] == 3'h6)
)
);
wire MSB_toggle_running_disparity =
(eight_bit_data_or_control_in[7:5] == 3'h0)
| (eight_bit_data_or_control_in[7:5] == 3'h4)
| (eight_bit_data_or_control_in[7:5] == 3'h7);
// Keep track of the running disparity. If 1'b1, the disparity is positive.
always @@(posedge clk)
begin
if (reset == 1'b1)
begin
Running_Disparity <= 1'b0; // start negative
end
else
begin
Running_Disparity <= Running_Disparity
^ LSB_toggle_running_disparity
^ MSB_toggle_running_disparity;
end
end
// Decide whether to invert the encoded data;
wire Invert_LSB = ( (Running_Disparity == 1'b1)
& (invert_LSB_if_input_disparity_is_positive == 1'b1) )
| ( (Running_Disparity == 1'b0)
& (invert_LSB_if_input_disparity_is_negative == 1'b1) );
wire Invert_MSB = ( ((Running_Disparity ^ LSB_toggle_running_disparity) == 1'b1)
& (invert_MSB_if_LSB_disparity_is_positive == 1'b1) )
| ( ((Running_Disparity ^ LSB_toggle_running_disparity) == 1'b0)
& (invert_MSB_if_LSB_disparity_is_negative == 1'b1) );
// Calculate the actual encoded data.
reg [9:0] ten_bit_encoded_data_out;
reg invalid_control;
always @@(posedge clk)
begin
if (reset == 1'b1)
begin
ten_bit_encoded_data_out[9:0] <= 10'h000;
invalid_control <= 1'b0;
end
else
begin
ten_bit_encoded_data_out[5:0] <=
{6{Invert_LSB}} ^ first_level_encoded_data[5:0];
ten_bit_encoded_data_out[9:6] <=
{4{Invert_MSB}} ^ first_level_encoded_data[9:6];
invalid_control <= input_is_control
& ~( LSB_is_28 // all MSB bits are valid
| ( LSB_is_23_27_29_30
& (eight_bit_data_or_control_in[7:5] == 3'h7) // MSB must be 7
)
);
end
end
endmodule
// Convert 10-bit code to 8-bit binary or 8-bit control code
module decode_10b_8b (
ten_bit_encoded_data_in,
eight_bit_data_or_control_out,
output_is_control,
invalid_encoded_data,
clk,
reset
);
input [9:0] ten_bit_encoded_data_in;
output [7:0] eight_bit_data_or_control_out;
output output_is_control;
output invalid_encoded_data;
input clk, reset;
// Data is encoded as described in the encode_8b_10b module above.
// This module tries to extract valid data or control info from the
// encoded input data.
//
// This module depends on the data being correctly 10-bit aligned.
// the LSB of the input must be the "a" bit as described above.
//
// This module tries to detect errors in the code sequence as it arrives.
// Errors are when an illegal bit sequence arrives, or when the disparity
// of the input data goes beyond 1 bit. This would happen if the sender
// did not correctly use alternate encodings of output data.
// Accumulate the new data. Calculate ignoring the running disparity;
wire [7:0] decoded_data;
// Calculate the values for the 6 -> 5 decoding
// Discover important details about the incoming numbers.
wire [1:0] LSB_02_Population = ten_bit_encoded_data_in[0] // full adder
+ ten_bit_encoded_data_in[1]
+ ten_bit_encoded_data_in[2];
wire [1:0] LSB_35_Population = ten_bit_encoded_data_in[3] // full adder
+ ten_bit_encoded_data_in[4]
+ ten_bit_encoded_data_in[5];
wire [2:0] LSB_bottom_4_Population = {1'b0, LSB_02_Population[1:0]}
+ {2'b00, ten_bit_encoded_data_in[3]};
wire [2:0] LSB_Population = {1'b0, LSB_02_Population[1:0]} // allowed: 2, 3, 4
+ {1'b0, LSB_35_Population[1:0]}; // illegal: 0, 1, 5, 6
// As can be seen, in many of the LSB encodings the bottom
// 4 of the decoded data are identical to the input
// data. (These are noted with a trailing "!")
//
// The bottom 4 bits can be used directly in these cases (which are all cases
// where the number of bits in the input are equil to 3 except for 7):
// 3 5 6 9 10 11 12 13 14 17 18 19 20 21 22 25 26 28
// The bottom 4 bits must be inverted before use in these cases: (MSB right)
// 011101 101101 110101 111001 000101 001001 010001 100001 000111 110000
wire LSB_Invert_Before_Use = ( (ten_bit_encoded_data_in[5:4] == 2'b10)
& ( (LSB_bottom_4_Population[2:0] == 3'h1)
| (LSB_bottom_4_Population[2:0] == 3'h3) )
)
| (ten_bit_encoded_data_in[5:0] == 6'b111000) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b000011);
// Values must be substituted in these cases:
wire LSB_is_0_16_a = (ten_bit_encoded_data_in[5:0] == 6'b000110) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b110110);
wire LSB_is_0_16_b = (ten_bit_encoded_data_in[5:0] == 6'b111001) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b001001);
wire LSB_is_15_31_a = (ten_bit_encoded_data_in[5:0] == 6'b000101) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b110101);
wire LSB_is_15_31_b = (ten_bit_encoded_data_in[5:0] == 6'b111010) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b001010);
wire LSB_is_24_a = (ten_bit_encoded_data_in[5:0] == 6'b001100); // LSB to right
wire LSB_is_24_b = (ten_bit_encoded_data_in[5:0] == 6'b110011); // LSB to right
// Notice when these codes occur. They are the only time Alternate D.x.7 data
// can be used. This is looked for below to detect errors.
wire LSB_is_11_13_14 = (ten_bit_encoded_data_in[5:0] == 6'b001011) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b001101)
| (ten_bit_encoded_data_in[5:0] == 6'b001110);
wire LSB_is_17_18_20 = (ten_bit_encoded_data_in[5:0] == 6'b110001) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b110010)
| (ten_bit_encoded_data_in[5:0] == 6'b110100);
// Control signals must be called out when recognized.
wire LSB_is_23_27_29_30 = ( (ten_bit_encoded_data_in[5:4] == 2'b01)
& (LSB_bottom_4_Population[2:0] == 3'h3) )
| ( (ten_bit_encoded_data_in[5:4] == 2'b10)
& (LSB_bottom_4_Population[2:0] == 3'h1) );
wire LSB_is_K28 = (ten_bit_encoded_data_in[5:0] == 6'b111100) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b000011);
// calculate the bottom 4 bits of decoded data
wire [3:0] LSB_XOR_Term = {4{LSB_Invert_Before_Use}} // invert all signals with alternate values
| {1'b0, LSB_is_0_16_a, LSB_is_0_16_a, 1'b0} // make 0, 16 into 0
| {LSB_is_0_16_b, 1'b0, 1'b0, LSB_is_0_16_b} // make 0, 16 into 0
| {LSB_is_15_31_a, 1'b0, LSB_is_15_31_a, 1'b0} // make 15, 31 into 15
| {1'b0, LSB_is_15_31_b, 1'b0, LSB_is_15_31_b} // make 15, 31 into 15
| {1'b0, LSB_is_24_a, 1'b0, 1'b0} // make 24 into 24
| {LSB_is_24_b, 1'b0, LSB_is_24_b, LSB_is_24_b}; // make 24 into 24
assign decoded_data[3:0] = ten_bit_encoded_data_in[3:0] ^ LSB_XOR_Term[3:0];
// The next bit is harder. I don't know if this is minimal
assign decoded_data[4] = (ten_bit_encoded_data_in[5:0] == 6'b001001) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b001010)
| (ten_bit_encoded_data_in[5:0] == 6'b001100)
| (ten_bit_encoded_data_in[5:3] == 3'b110)
| ( (ten_bit_encoded_data_in[5:4] == 2'b01)
& (LSB_bottom_4_Population[2:0] == 3'h2) )
| LSB_is_23_27_29_30
| LSB_is_K28;
// Calculate the values for the 4 -> 3 decoding
// The bottom 2 bits of the MSB must always be inverted before use in these
// cases: (MSB right) 0011, 1101, 0001
// When the LSB indicate that the byte contains a K28, and the bottom 6 bits
// have a negative disparity, invert these before using: (MSB right)
// 0110, 1010, 0101, 1001
// Only 2 of these are needed to greate singular commas. I don't understand
// why they made the other special cases. Very odd
wire MSB_Invert_Before_Use = (ten_bit_encoded_data_in[9:6] == 4'b1100) // LSB to right
| (ten_bit_encoded_data_in[9:6] == 4'b1011)
| (ten_bit_encoded_data_in[9:6] == 4'b1000)
| ( (ten_bit_encoded_data_in[5:0] == 6'b000011)
& ( (ten_bit_encoded_data_in[9:6] == 4'b0110)
| (ten_bit_encoded_data_in[9:6] == 4'b0101)
| (ten_bit_encoded_data_in[9:6] == 4'b1010)
| (ten_bit_encoded_data_in[9:6] == 4'b1001)
)
);
// Values must be substituted in these cases:
wire MSB_0_value_a = (ten_bit_encoded_data_in[9:6] == 4'b0010); // LSB to right
wire MSB_0_value_b = (ten_bit_encoded_data_in[9:6] == 4'b1101);
wire alternate_MSB_a = (ten_bit_encoded_data_in[9:6] == 4'b1110); // LSB to right
wire alternate_MSB_b = (ten_bit_encoded_data_in[9:6] == 4'b0001);
wire primary_MSB_a = (ten_bit_encoded_data_in[9:6] == 4'b0111); // LSB to right
wire primary_MSB_b = (ten_bit_encoded_data_in[9:6] == 4'b1000);
wire [2:0] MSB_XOR_Term = {3{MSB_Invert_Before_Use}}
| {1'b0, MSB_0_value_a, 1'b0}
| {MSB_0_value_b, 1'b0, MSB_0_value_b}
| {1'b0, 1'b0, alternate_MSB_a}
| {alternate_MSB_b, alternate_MSB_b, 1'b0};
assign decoded_data[7:5] = ten_bit_encoded_data_in[8:6] ^ MSB_XOR_Term[2:0];
wire decoded_control = ( LSB_is_23_27_29_30
& (alternate_MSB_a | alternate_MSB_b))
| LSB_is_K28;
// Keep track of the running disparity. If 1'b1, the disparity is positive.
wire [1:0] MSB_01_Population = ten_bit_encoded_data_in[6] // half adder
+ ten_bit_encoded_data_in[7];
wire [1:0] MSB_23_Population = ten_bit_encoded_data_in[8] // half adder
+ ten_bit_encoded_data_in[9];
wire [2:0] MSB_Population = {1'b0, MSB_01_Population[1:0]} // 1, 2, 3
+ {1'b0, MSB_23_Population[1:0]};
wire [3:0] Code_Population = {1'b0, LSB_Population[2:0]} // 4, 5, 6
+ {1'b0, MSB_Population[2:0]};
reg Running_Disparity;
always @@(posedge clk)
begin
if (reset == 1'b1)
begin
Running_Disparity <= 1'b0; // start negative
end
else
begin
Running_Disparity <= (Code_Population[3:0] == 4'h6)
? 1'b1
: ( (Code_Population[3:0] == 4'h4)
? 1'b0
: Running_Disparity);
end
end
// Detect invalid code values.
wire too_many_bits_in_first_nibble =
(LSB_bottom_4_Population[2:0] > 3'h3);
wire too_few_bits_in_first_nibble =
(LSB_bottom_4_Population[2:0] < 3'h1);
wire too_many_bits_in_LSB = (LSB_Population[2:0] > 3'h4);
wire too_few_bits_in_LSB = (LSB_Population[2:0] < 3'h2);
wire too_many_bits_in_MSB = (MSB_Population[2:0] > 3'h3);
wire too_few_bits_in_MSB = (LSB_Population[2:0] < 3'h1);
wire too_many_bits_in_entire_code = (Code_Population[3:0] > 4'h6);
wire too_few_bits_in_entire_code = (Code_Population[3:0] < 4'h4);
wire LSB_inconsistent_with_running_disparity =
( (Running_Disparity == 1'b1)
& ( (LSB_Population[2:0] == 3'h4)
| (ten_bit_encoded_data_in[5:0] == 6'b000111) // X.7 negative disparity
) )
| ( (Running_Disparity == 1'b0)
& ( (LSB_Population[2:0] == 3'h2)
| (ten_bit_encoded_data_in[5:0] == 6'b111000) // X.7 positive disparity
) );
wire LSB_code_7_positive_but_MSB_inconsistent =
(ten_bit_encoded_data_in[5:0] == 6'b111000) // X.7 positive disparity
& ( (MSB_Population[2:0] == 3'h3) // too many bits in MSB
| (ten_bit_encoded_data_in[9:6] == 4'b0011) // Y.3 negative disparity
);
wire LSB_code_7_negative_but_MSB_inconsistent =
(ten_bit_encoded_data_in[5:0] == 6'b000111) // X.7 negative disparity
& ( (MSB_Population[2:0] == 3'h1) // too few bits in MSB
| (ten_bit_encoded_data_in[9:6] == 4'b1100) // Y.3 positive disparity
);
wire MSB_code_3_positive_but_LSB_inconsistent =
(ten_bit_encoded_data_in[9:6] == 4'b1100) // X.7 positive disparity
& (LSB_Population[2:0] == 3'h2); // too few bits in LSB
wire MSB_code_3_negative_but_LSB_inconsistent =
(ten_bit_encoded_data_in[9:6] == 4'b0011) // X.7 negative disparity
& (LSB_Population[2:0] == 3'h4); // too many bits in LSB
wire alternate_encoding_not_used_when_required =
((Running_Disparity == 1'b1) & (LSB_is_11_13_14) & primary_MSB_b)
| ((Running_Disparity == 1'b0) & (LSB_is_17_18_20) & primary_MSB_a)
| (LSB_is_K28 & (primary_MSB_a | primary_MSB_b));
wire primary_encoding_not_used_when_required =
((Running_Disparity == 1'b0) & (LSB_is_11_13_14) & alternate_MSB_b)
| ((Running_Disparity == 1'b1) & (LSB_is_17_18_20) & alternate_MSB_a);
wire detected_invalid_8b_10b_sequence = too_many_bits_in_first_nibble
| too_few_bits_in_first_nibble
| too_many_bits_in_LSB
| too_few_bits_in_LSB
| too_many_bits_in_MSB
| too_few_bits_in_MSB
| too_many_bits_in_entire_code
| too_few_bits_in_entire_code
| LSB_inconsistent_with_running_disparity
| LSB_code_7_positive_but_MSB_inconsistent
| LSB_code_7_negative_but_MSB_inconsistent
| MSB_code_3_positive_but_LSB_inconsistent
| MSB_code_3_negative_but_LSB_inconsistent
| alternate_encoding_not_used_when_required
| primary_encoding_not_used_when_required;
// Calculate the actual decoded data.
reg [7:0] eight_bit_data_or_control_out;
reg output_is_control;
reg invalid_encoded_data;
always @@(posedge clk)
begin
if (reset == 1'b1)
begin
eight_bit_data_or_control_out[7:0] <= 8'h00;
output_is_control <= 1'b0;
invalid_encoded_data <= 1'b0;
end
else
begin
eight_bit_data_or_control_out[7:0] <= decoded_data[7:0];
output_is_control <= decoded_control;
invalid_encoded_data <= detected_invalid_8b_10b_sequence
& (ten_bit_encoded_data_in[9:0] != 10'b0000_000000) // NOTE TEMPORARY
;
end
end
endmodule
// `define TEST_8B_10B
`ifdef TEST_8B_10B
// This simulates in between 6 and 7 minutes on a 400 MHz Ultra using verilog XL.
// This does not complete before filling up the disk on a 300 MHz K6 using Verilogger PRO.
module test_8b_10b;
reg [8:0] test_data;
reg [8:0] test_data_second;
reg [8:0] limit;
reg [7:0] control_byte;
reg [7:0] control_byte_second;
reg test_control;
reg [7:0] eight_bit_data_or_control_in;
reg input_is_control;
reg mess_up_link_disparity;
wire [9:0] ten_bit_encoded_data_out;
wire invalid_control;
wire [7:0] eight_bit_data_or_control_out;
wire output_is_control;
wire invalid_encoded_data;
reg clk, reset;
reg found_singular_comma;
task set_to_negative_disparity;
begin
clk = 1'b0; reset = 1'b1; #1;
clk = 1'b1; reset = 1'b1; #1; // do reset, setting sender to negative disparity
clk = 1'b0; reset = 1'b1; #1;
clk = 1'b0; reset = 1'b0; #1;
end
endtask
task set_to_positive_disparity;
begin
clk = 1'b0; reset = 1'b1; #1;
clk = 1'b1; reset = 1'b1; #1; // do reset, setting sender to negative disparity
clk = 1'b0; reset = 1'b1; #1;
clk = 1'b0; reset = 1'b0; #1;
eight_bit_data_or_control_in[7:0] = 8'b111_00011; #1;
clk = 1'b1; #1; // switch to a positive running disparity
clk = 1'b0; #1;
end
endtask
task check;
input disparity;
input [7:0] test_data;
input do_control;
reg [9:0] latched_code;
begin
if (disparity == 1'b1)
set_to_positive_disparity;
else
set_to_negative_disparity;
input_is_control = do_control;
eight_bit_data_or_control_in[7:0] = test_data[7:0]; #1; // inputs settle
clk = 1'b1; #1; // encoded data available
clk = 1'b0; #1;
latched_code[9:0] = ten_bit_encoded_data_out[9:0];
input_is_control = 1'b0;
eight_bit_data_or_control_in[7:0] = 8'b010_00011; #1;
clk = 1'b1; #1; // decoded data available
clk = 1'b0; #1;
if ( (eight_bit_data_or_control_out[7:0] !== test_data[7:0])
| (output_is_control !== do_control)
| (invalid_encoded_data !== 1'b0)
)
begin
$display ("!!! test data, result %d %d %b_%b %x %d %b %b",
test_data[7:5], test_data[4:0],
latched_code[9:6], latched_code[5:0],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
end
endtask
function look_for_singular_comma;
input [6:0] data;
begin
if ( (data[0] == data[1])
& (data[0] == ~data[2])
& (data[0] == ~data[3])
& (data[0] == ~data[4])
& (data[0] == ~data[5])
& (data[0] == ~data[6])
)
begin
look_for_singular_comma = 1'b1;
end
else
begin
look_for_singular_comma = 1'b0;
end
end
endfunction
task check_pair; // Data then Data or Control then Data
input disparity;
input [7:0] test_data;
input [7:0] test_data_second;
input do_control;
input want_singular_comma;
reg [9:0] latched_code;
reg [19:0] two_bytes_of_codes_back_to_back;
begin
if (disparity == 1'b1)
set_to_positive_disparity;
else
set_to_negative_disparity;
input_is_control = do_control;
eight_bit_data_or_control_in[7:0] = test_data[7:0]; #1; // inputs settle
clk = 1'b1; #1; // encoded data available
clk = 1'b0; #1;
latched_code[9:0] = ten_bit_encoded_data_out[9:0];
two_bytes_of_codes_back_to_back[9:0] = ten_bit_encoded_data_out[9:0];
input_is_control = 1'b0;
eight_bit_data_or_control_in[7:0] = test_data_second[7:0]; #1; // inputs settle
clk = 1'b1; #1; // decoded data available
clk = 1'b0; #1;
if ( (eight_bit_data_or_control_out[7:0] !== test_data[7:0])
| (output_is_control !== do_control)
| (invalid_encoded_data !== 1'b0)
)
begin
$display ("!!! test data, result %d %d %b_%b %x %d %b %b",
test_data[7:5], test_data[4:0],
latched_code[9:6], latched_code[5:0],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
latched_code[9:0] = ten_bit_encoded_data_out[9:0];
two_bytes_of_codes_back_to_back[19:10] = ten_bit_encoded_data_out[9:0];
input_is_control = 1'b0;
eight_bit_data_or_control_in[7:0] = 8'b010_00011; #1;
clk = 1'b1; #1; // decoded data available
clk = 1'b0; #1;
if ( (eight_bit_data_or_control_out[7:0] !== test_data_second[7:0])
| (output_is_control !== 1'b0)
| (invalid_encoded_data !== 1'b0)
)
begin
$display ("!!! test data second, result %d %d %b_%b %x %d %b %b",
test_data_second[7:5], test_data_second[4:0],
latched_code[9:6], latched_code[5:0],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
if (~want_singular_comma)
begin
if ( look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
begin
$display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
end
else // want a singular comma
begin
if (!look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0]))
begin
$display ("!!! missing singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
if ( look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
begin
$display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
end
end
endtask
task check_pair_2; // Data followed by Control or Control followed by Control
input disparity;
input [7:0] test_data;
input [7:0] test_data_second;
input first_control;
input want_first_singular_comma;
input second_control;
input want_second_singular_comma;
reg [9:0] latched_code;
reg [19:0] two_bytes_of_codes_back_to_back;
begin
if (disparity == 1'b1)
set_to_positive_disparity;
else
set_to_negative_disparity;
input_is_control = first_control;
eight_bit_data_or_control_in[7:0] = test_data[7:0]; #1; // inputs settle
clk = 1'b1; #1; // encoded data available
clk = 1'b0; #1;
latched_code[9:0] = ten_bit_encoded_data_out[9:0];
two_bytes_of_codes_back_to_back[9:0] = ten_bit_encoded_data_out[9:0];
input_is_control = second_control;
eight_bit_data_or_control_in[7:0] = test_data_second[7:0]; #1; // inputs settle
clk = 1'b1; #1; // decoded data available
clk = 1'b0; #1;
if ( (eight_bit_data_or_control_out[7:0] !== test_data[7:0])
| (output_is_control !== first_control)
| (invalid_encoded_data !== 1'b0)
)
begin
$display ("!!! test data, result %d %d %b_%b %x %d %b %b",
test_data[7:5], test_data[4:0],
latched_code[9:6], latched_code[5:0],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
latched_code[9:0] = ten_bit_encoded_data_out[9:0];
two_bytes_of_codes_back_to_back[19:10] = ten_bit_encoded_data_out[9:0];
input_is_control = 1'b0;
eight_bit_data_or_control_in[7:0] = 8'b010_00011; #1;
clk = 1'b1; #1; // decoded data available
clk = 1'b0; #1;
if ( (eight_bit_data_or_control_out[7:0] !== test_data_second[7:0])
| (output_is_control !== second_control)
| (invalid_encoded_data !== 1'b0)
)
begin
$display ("!!! test data second, result %d %d %b_%b %x %d %b %b",
test_data_second[7:5], test_data_second[4:0],
latched_code[9:6], latched_code[5:0],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
if (~want_first_singular_comma)
begin
if ( look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9]) )
begin
$display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
end
else // want a singular comma in the first byte
begin
if (!look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0]))
begin
$display ("!!! missing singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
if ( look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9]) )
begin
$display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
end
if (~want_second_singular_comma)
begin
if ( look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
begin
$display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
end
else // want a singular comma in the second byte
begin
if (!look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10]))
begin
$display ("!!! missing singular comma 2, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
if ( look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
| look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
begin
$display ("!!! unexpected singular comma 2, result %d %d %b_%b %b_%b %b %b %b %b",
test_data[7:0], test_data_second[7:0],
two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
output_is_control, invalid_encoded_data);
end
end
end
endtask
function [7:0] pick_control_byte;
input [3:0] index;
begin
case (index[3:0])
0: pick_control_byte[7:0] = `K_23_7;
1: pick_control_byte[7:0] = `K_27_7;
2: pick_control_byte[7:0] = `K_28_0;
3: pick_control_byte[7:0] = `K_28_1;
4: pick_control_byte[7:0] = `K_28_2;
5: pick_control_byte[7:0] = `K_28_3;
6: pick_control_byte[7:0] = `K_28_4;
7: pick_control_byte[7:0] = `K_28_5;
8: pick_control_byte[7:0] = `K_28_6;
9: pick_control_byte[7:0] = `K_28_7;
10: pick_control_byte[7:0] = `K_29_7;
default: pick_control_byte[7:0] = `K_30_7;
endcase
end
endfunction
initial
begin
mess_up_link_disparity = 1'b0;
$display ("test 32 LSB data values starting with negative disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h020;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (0, test_data[7:0], 1'b0);
end
$display ("test 8 MSB data values starting with negative disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (0, (test_data[2:0] << 5) | 5'h03, 1'b0);
end
$display ("test 8 MSB data values starting with negative disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (0, (test_data[2:0] << 5) | 5'h0B, 1'b0); // 11
end
$display ("test 8 MSB data values starting with negative disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (0, (test_data[2:0] << 5) | 5'h11, 1'b0); // 17
end
$display ("test control starting with negative disparity");
check (0, `K_23_7, 1'b1);
check (0, `K_27_7, 1'b1);
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (0, `K_28_0 | (test_data[2:0] << 5), 1'b1);
end
check (0, `K_29_7, 1'b1);
check (0, `K_30_7, 1'b1);
// $display ("invalid control character with negative disparity");
// check (0, 8'h0, 1'b1);
$display ("test 32 LSB data values starting with positive disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h020;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (1, test_data[7:0], 1'b0);
end
$display ("test 8 MSB data values starting with positive disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (1, (test_data[2:0] << 5) | 5'h03, 1'b0);
end
$display ("test 8 MSB data values starting with positive disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (1, (test_data[2:0] << 5) | 5'h0B, 1'b0); // 11
end
$display ("test 8 MSB data values starting with positive disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (1, (test_data[2:0] << 5) | 5'h11, 1'b0); // 17
end
$display ("test control starting with positive disparity");
check (1, `K_23_7, 1'b1);
check (1, `K_27_7, 1'b1);
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
check (1, `K_28_0 | (test_data[2:0] << 5), 1'b1);
end
check (1, `K_29_7, 1'b1);
check (1, `K_30_7, 1'b1);
// $display ("invalid control character with positive disparity");
// check (1, 8'h0, 1'b1);
limit[8:0] = 9'h100; # 1;
$display ("trying all byte pairs starting with negative disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
for (test_data_second[8:0] = 9'h000; test_data_second[8:0] < limit[8:0];
test_data_second[8:0] = test_data_second[8:0] + 9'h001)
begin
check_pair (0, test_data[7:0], test_data_second[7:0], 1'b0, 1'b0);
end
end
$display ("trying all controls then bytes with negative disparity");
$display ("This finds 24 unexpected extra singular commas when sending K_28_7");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
test_data_second[3:0] = test_data_second[3:0] + 4'h1)
begin
check_pair (0, pick_control_byte(test_data_second[3:0]), test_data[7:0], 1'b1,
(test_data_second[3:0] == 4'h3)
| (test_data_second[3:0] == 4'h7)
| (test_data_second[3:0] == 4'h9) );
end
end
$display ("trying all bytes then controls with negative disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
test_data_second[3:0] = test_data_second[3:0] + 4'h1)
begin
check_pair_2 (0, test_data[7:0], pick_control_byte(test_data_second[3:0]),
1'b0, 1'b0,
1'b1, (test_data_second[3:0] == 4'h3)
| (test_data_second[3:0] == 4'h7)
| (test_data_second[3:0] == 4'h9) );
end
end
$display ("trying all controls then controls with negative disparity");
$display ("This finds 8 unexpected extra singular commas when sending K_28_7");
for (test_data[3:0] = 9'h000; test_data[3:0] < 4'hC;
test_data[3:0] = test_data[3:0] + 4'h1)
begin
for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
test_data_second[3:0] = test_data_second[3:0] + 4'h1)
begin
check_pair_2 (0, pick_control_byte(test_data[3:0]),
pick_control_byte(test_data_second[3:0]),
1'b1, (test_data[3:0] == 4'h3)
| (test_data[3:0] == 4'h7)
| (test_data[3:0] == 4'h9),
1'b1, (test_data_second[3:0] == 4'h3)
| (test_data_second[3:0] == 4'h7)
| (test_data_second[3:0] == 4'h9) );
end
end
$display ("trying all byte pairs starting with positive disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
for (test_data_second[8:0] = 9'h000; test_data_second[8:0] < limit[8:0];
test_data_second[8:0] = test_data_second[8:0] + 9'h001)
begin
check_pair (1, test_data[7:0], test_data_second[7:0], 1'b0, 1'b0);
end
end
$display ("trying all controls then bytes with positive disparity");
$display ("This finds 24 unexpected extra singular commas when sending K_28_7");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
test_data_second[3:0] = test_data_second[3:0] + 4'h1)
begin
check_pair (1, pick_control_byte(test_data_second[3:0]), test_data[7:0], 1'b1,
(test_data_second[3:0] == 4'h3)
| (test_data_second[3:0] == 4'h7)
| (test_data_second[3:0] == 4'h9) );
end
end
$display ("trying all bytes then controls with positive disparity");
for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
test_data[8:0] = test_data[8:0] + 9'h001)
begin
for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
test_data_second[3:0] = test_data_second[3:0] + 4'h1)
begin
check_pair_2 (1, test_data[7:0], pick_control_byte(test_data_second[3:0]),
1'b0, 1'b0,
1'b1, (test_data_second[3:0] == 4'h3)
| (test_data_second[3:0] == 4'h7)
| (test_data_second[3:0] == 4'h9) );
end
end
$display ("trying all controls then controls with positive disparity");
$display ("This finds 8 unexpected extra singular commas when sending K_28_7");
for (test_data[3:0] = 9'h000; test_data[3:0] < 4'hC;
test_data[3:0] = test_data[3:0] + 4'h1)
begin
for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
test_data_second[3:0] = test_data_second[3:0] + 4'h1)
begin
check_pair_2 (1, pick_control_byte(test_data[3:0]),
pick_control_byte(test_data_second[3:0]),
1'b1, (test_data[3:0] == 4'h3)
| (test_data[3:0] == 4'h7)
| (test_data[3:0] == 4'h9),
1'b1, (test_data_second[3:0] == 4'h3)
| (test_data_second[3:0] == 4'h7)
| (test_data_second[3:0] == 4'h9) );
end
end
end
encode_8b_10b encode_8b_10b (
.eight_bit_data_or_control_in (eight_bit_data_or_control_in[7:0]),
.input_is_control (input_is_control),
.mess_up_link_disparity (mess_up_link_disparity),
.ten_bit_encoded_data_out (ten_bit_encoded_data_out[9:0]),
.invalid_control (invalid_control),
.clk (clk),
.reset (reset)
);
decode_10b_8b decode_10b_8b (
.ten_bit_encoded_data_in (ten_bit_encoded_data_out[9:0]),
.eight_bit_data_or_control_out (eight_bit_data_or_control_out[7:0]),
.output_is_control (output_is_control),
.invalid_encoded_data (invalid_encoded_data),
.clk (clk),
.reset (reset)
);
endmodule
`endif // TEST_8B_10B
// `define DISCOVER_WHICH_CODES_ARE_ILLEGAL
`ifdef DISCOVER_WHICH_CODES_ARE_ILLEGAL
module figure_out_error_patterns;
// NOTE: For the purpose of comparing with the patent, this exploration
// module uses the notation that the LEFTMOST BIT is the LSB.
// All other modules use the more normal Rightmost Bit == bit 0 == LSB
reg [10:0] i;
reg [9:0] full_addr;
reg [4095:0] valid; // storage
reg [4095:0] invalid; // storage
task do_one;
input [3:0] high_addr;
begin
full_addr[3:0] = high_addr[3:0]; // note LSB to left
valid[full_addr[9:0]] = 1'b1;
end
endtask
task mark_both;
begin
// both
do_one (4'b1001);
do_one (4'b0101);
do_one (4'b1010);
do_one (4'b0110);
end
endtask
// The alternate Data encoding D.x.A7 is used in the case
// that e = i = 0 and positive running disparity,
// or e = i = 1 and negative running disparity,
// or a Control signal is being sent,
// all while encoding 7 in the MSB.
task mark_positive;
begin
// positive list
do_one (4'b0100);
do_one (4'b0011);
do_one (4'b0010);
if (full_addr[5:4] != 2'b00)
do_one (4'b0001); // P
else
do_one (4'b1000); // A
end
endtask
task mark_negative;
begin
// negative list
do_one (4'b1011);
do_one (4'b1100);
do_one (4'b1101);
if (full_addr[5:4] != 2'b11)
do_one (4'b1110); // P
else
do_one (4'b0111); // A
end
endtask
task mark_all;
begin
mark_positive;
mark_negative;
mark_both;
end
endtask
task mark;
input [5:0] val;
input type;
integer type;
begin
full_addr[9:4] = val[5:0]; // note LSB to left
if (type == 0)
begin
mark_all;
end
else if (type == 1)
begin
mark_positive;
mark_both;
end
else
begin
mark_negative;
mark_both;
end
end
endtask
initial
begin
// Clear all bits
for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
begin
valid[i[9:0]] = 1'b0;
invalid[full_addr[9:0]] = 1'b0;
end
// Mark patterns which are parts of valid codes
mark (6'b110001, 0);
mark (6'b101001, 0);
mark (6'b011001, 0);
mark (6'b100101, 0);
mark (6'b010101, 0);
mark (6'b110100, 0);
mark (6'b001101, 0);
mark (6'b101100, 0);
mark (6'b011100, 0);
mark (6'b100011, 0);
mark (6'b010011, 0);
mark (6'b110010, 0);
mark (6'b001011, 0);
mark (6'b101010, 0);
mark (6'b011010, 0);
mark (6'b100110, 0);
mark (6'b010110, 0);
mark (6'b001110, 0);
mark (6'b011000, -1);
mark (6'b100010, -1);
mark (6'b010010, -1);
mark (6'b001010, -1);
mark (6'b111000, -1);
mark (6'b000110, -1);
mark (6'b101000, -1);
mark (6'b100100, -1);
mark (6'b000101, -1);
mark (6'b001100, -1);
mark (6'b001001, -1);
mark (6'b010001, -1);
mark (6'b100001, -1);
mark (6'b010100, -1);
mark (6'b100111, +1);
mark (6'b011101, +1);
mark (6'b101101, +1);
mark (6'b110101, +1);
mark (6'b000111, +1);
mark (6'b111001, +1);
mark (6'b010111, +1);
mark (6'b011011, +1);
mark (6'b111010, +1);
mark (6'b110011, +1);
mark (6'b110110, +1);
mark (6'b101110, +1);
mark (6'b011110, +1);
mark (6'b101011, +1);
// Mark patterns which are control codes.
valid[ 10'b111010_1000] = 1'b1;
valid[ 10'b110110_1000] = 1'b1;
valid[ 10'b101110_1000] = 1'b1;
valid[ 10'b011110_1000] = 1'b1;
valid[ 10'b001111_0100] = 1'b1;
valid[ 10'b001111_1001] = 1'b1;
valid[ 10'b001111_0101] = 1'b1;
valid[ 10'b001111_0011] = 1'b1;
valid[ 10'b001111_0010] = 1'b1;
valid[ 10'b001111_1010] = 1'b1;
valid[ 10'b001111_0110] = 1'b1;
valid[ 10'b001111_1000] = 1'b1;
valid[~10'b111010_1000] = 1'b1;
valid[~10'b110110_1000] = 1'b1;
valid[~10'b101110_1000] = 1'b1;
valid[~10'b011110_1000] = 1'b1;
valid[~10'b001111_0100] = 1'b1;
valid[~10'b001111_1001] = 1'b1;
valid[~10'b001111_0101] = 1'b1;
valid[~10'b001111_0011] = 1'b1;
valid[~10'b001111_0010] = 1'b1;
valid[~10'b001111_1010] = 1'b1;
valid[~10'b001111_0110] = 1'b1;
valid[~10'b001111_1000] = 1'b1;
for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
begin
// Get rid of patterns in the 6 LSB with less than 2 or greater than 4 bits set.
if ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) < 2)
begin
invalid[i[9:0]] = 1'b1;
end
if ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) > 4)
begin
invalid[i[9:0]] = 1'b1;
end
// Get rid of patterns in the 4 MSB with less than 1 or greater than 3 bits set.
if ((i[3:0] == 4'h0) | (i[3:0] == 4'hF))
begin
invalid[i[9:0]] = 1'b1;
end
// Get rid of total patterns with less than 4 or greater than 6 bits set.
if ((i[0] + i[1] + i[2] + i[3] + i[4] + i[5] + i[6] + i[7] + i[8] + i[9]) < 4)
begin
invalid[i[9:0]] = 1'b1;
end
if ((i[0] + i[1] + i[2] + i[3] + i[4] + i[5] + i[6] + i[7] + i[8] + i[9]) > 6)
begin
invalid[i[9:0]] = 1'b1;
end
// Get rid of patterns with the 4 LSB all 0 or all 1
if ((i[9:6] == 4'b0000) | (i[9:6] == 4'b1111))
begin
invalid[i[9:0]] = 1'b1;
end
// Get rid of patterns which use D.7.y with the wrong disparity. 8
if ((i[9:4] == 6'b111000) & (i[3] + i[2] + i[1] + i[0] == 1)) // minus then minus
begin
invalid[i[9:0]] = 1'b1;
end
if ((i[9:4] == 6'b000111) & (i[3] + i[2] + i[1] + i[0] == 3)) // plus then plus
begin
invalid[i[9:0]] = 1'b1;
end
// Get rid of patterns which use D.x.3 with the wrong disparity. 28
if ( (i[3:0] == 4'b0011)
& ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) == 2))
begin
invalid[i[9:0]] = 1'b1;
end
if ( (i[3:0] == 4'b1100)
& ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) == 4))
begin
invalid[i[9:0]] = 1'b1;
end
end
// Get rid of case when D.x.3 and D.7.y are used together as D.7.3
valid[10'b111000_0011] = 1'b1;
valid[10'b000111_1100] = 1'b1;
for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
begin
// Get rid of non-control codes which use alternate encoding inappropriately. 32
// These are all the data items except 23, 27, 29, and 30 which do not end in
// 00 or 11 as the MSB. This excludes control codes, which use alternate encoding.
if ( (i[9:4] != 6'b111010) & (i[9:4] != 6'b000101) // 23
& (i[9:4] != 6'b110110) & (i[9:4] != 6'b001001) // 27
& (i[9:4] != 6'b101110) & (i[9:4] != 6'b010001) // 29
& (i[9:4] != 6'b011110) & (i[9:4] != 6'b100001) // 30
& (i[9:4] != 6'b001111) & (i[9:4] != 6'b110000) // K28
& (i[9:4] != 6'b110100) // 11
& (i[9:4] != 6'b101100) // 13
& (i[9:4] != 6'b011100) // 14
& (i[9:4] != 6'b100011) // 17
& (i[9:4] != 6'b010011) // 18
& (i[9:4] != 6'b001011) // 20
)
begin
if ((i[3:0] == 4'b0111) | (i[3:0] == 4'b1000))
begin
invalid[i[9:0]] = 1'b1; // not a candidate for alternate D7 at all
end
end
if ( (i[9:4] == 6'b110000) // K28
| (i[9:4] == 6'b001111) // K28
| (i[9:4] == 6'b110100) // 11
| (i[9:4] == 6'b101100) // 13
| (i[9:4] == 6'b011100) // 14
)
begin
if (i[3:0] == 4'b0001) // cant use normal +
begin
invalid[i[9:0]] = 1'b1;
end
end
if ( (i[9:4] == 6'b100011) // 17
| (i[9:4] == 6'b010011) // 18
| (i[9:4] == 6'b001011) // 20
)
begin
if (i[3:0] == 4'b1000) // cant use alternate +
begin
invalid[i[9:0]] = 1'b1;
end
end
if ( (i[9:4] == 6'b110000) // K28
| (i[9:4] == 6'b001111) // K28
| (i[9:4] == 6'b100011) // 17
| (i[9:4] == 6'b010011) // 18
| (i[9:4] == 6'b001011) // 20
)
begin
if (i[3:0] == 4'b1110) // cant use normal -
begin
invalid[i[9:0]] = 1'b1;
end
end
if ( (i[9:4] == 6'b110100) // 11
| (i[9:4] == 6'b101100) // 13
| (i[9:4] == 6'b011100) // 14
)
begin
if (i[3:0] == 4'b0111) // cant use alternate -
begin
invalid[i[9:0]] = 1'b1;
end
end
end
$display ("LSB is to the left");
for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
begin
if ((valid[i[9:0]] !== 1'b1) & (invalid[i[9:0]] !== 1'b1))
begin
$display ("not set %b", i[9:0]);
end
if ((valid[i[9:0]] === 1'b1) & (invalid[i[9:0]] === 1'b1))
begin
$display ("both set %b", i[9:0]);
end
end
end
endmodule
`endif // DISCOVER_WHICH_CODES_ARE_ILLEGAL
@
1.5
log
@no message
@
text
@d66 1
a66 1
// $Id: encode_8b_10b.v,v 1.18 2001/10/26 10:39:43 Blue Beaver Exp $
d71 3
d271 30
a300 1
@
1.4
log
@no message
@
text
@d66 1
a66 1
// $Id: encode_8b_10b.v,v 1.14 2001/10/25 11:33:51 Blue Beaver Exp $
d71 9
a746 1
reg [19:0] two_bytes_of_codes_back_to_back;
d767 1
a767 1
`define TEST_8B_10B
d769 2
d775 2
a790 1
reg [19:0] two_bytes_of_codes_back_to_back;
d872 1
a872 1
task check_pair;
d879 2
d943 5
a947 1
| look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9]) )
d959 99
a1057 1
if ( !look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0])
d1068 12
d1087 55
d1146 20
d1269 1
d1273 8
a1280 12
check_pair (0, `K_23_7, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_27_7, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_28_0, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_28_1, test_data[7:0], 1'b1, 1'b1);
check_pair (0, `K_28_2, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_28_3, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_28_4, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_28_5, test_data[7:0], 1'b1, 1'b1);
check_pair (0, `K_28_6, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_28_7, test_data[7:0], 1'b1, 1'b1);
check_pair (0, `K_29_7, test_data[7:0], 1'b1, 1'b0);
check_pair (0, `K_30_7, test_data[7:0], 1'b1, 1'b0);
d1284 14
d1299 17
d1329 1
d1333 8
a1340 12
check_pair (1, `K_23_7, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_27_7, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_28_0, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_28_1, test_data[7:0], 1'b1, 1'b1);
check_pair (1, `K_28_2, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_28_3, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_28_4, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_28_5, test_data[7:0], 1'b1, 1'b1);
check_pair (1, `K_28_6, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_28_7, test_data[7:0], 1'b1, 1'b1);
check_pair (1, `K_29_7, test_data[7:0], 1'b1, 1'b0);
check_pair (1, `K_30_7, test_data[7:0], 1'b1, 1'b0);
d1344 14
a1357 1
// NOTE: TODO
d1359 17
a1375 1
@
1.3
log
@no message
@
text
@d66 1
a66 1
// $Id: encode_8b_10b.v,v 1.13 2001/10/24 11:38:02 Blue Beaver Exp $
d71 3
d250 9
a258 1
// K.28.1 or K.28.5 or K.28.7.
d738 1
d763 2
d779 3
d807 1
a807 1
input test_control;
d815 1
a815 1
input_is_control = test_control;
d828 1
a828 1
| (output_is_control !== test_control)
d841 123
d1052 67
@
1.2
log
@no message
@
text
@d66 1
a66 1
// $Id: encode_8b_10b.v,v 1.9 2001/10/23 10:34:50 Blue Beaver Exp $
d71 12
d138 1
d147 1
d255 4
a258 6
wire [1:0] LSB_02_Population = eight_bit_data_or_control_in[0] // full adder
+ eight_bit_data_or_control_in[1]
+ eight_bit_data_or_control_in[2];
wire [1:0] LSB_34_Population = eight_bit_data_or_control_in[3] // full adder
+ eight_bit_data_or_control_in[4];
d276 8
a302 5
wire LSB_contains_other_i = (eight_bit_data_or_control_in[3:0] == 4'h0)
| (eight_bit_data_or_control_in[3:0] == 4'h1)
| (eight_bit_data_or_control_in[3:0] == 4'h2)
| (eight_bit_data_or_control_in[3:0] == 4'h4);
d315 1
a315 1
wire LSB_term_has_positive_disparity =
d319 2
a320 2
& (eight_bit_data_or_control_in[4] == 1'b1))
| input_is_control;
d322 6
a327 5
wire LSB_term_has_negative_disparity =
( LSB_all_zero
| LSB_contains_one_one
| LSB_all_one)
& (eight_bit_data_or_control_in[4] == 1'b0);
d330 2
a331 1
LSB_term_has_positive_disparity | LSB_is_7;
d334 1
a334 1
LSB_term_has_negative_disparity | LSB_is_24;
d337 2
a338 2
LSB_term_has_positive_disparity
| invert_LSB_if_input_disparity_is_negative;
a373 3
wire MSB_all_zero = (eight_bit_data_or_control_in[7] == 1'h0)
& (eight_bit_data_or_control_in[5] == 1'h0);
d375 1
a375 1
| MSB_all_zero;
d399 3
a401 1
| (eight_bit_data_or_control_in[7:5] == 3'h6) ));
a422 2
// disparity_from_LSB
d438 1
a438 2
// always @@(posedge clk)
always @@(Invert_LSB or Invert_MSB or first_level_encoded_data or eight_bit_data_or_control_in or input_is_control)
d453 1
a453 5
| ( ( (eight_bit_data_or_control_in[4:0] == 5'h17) // 23
| (eight_bit_data_or_control_in[4:0] == 5'h1B) // 27
| (eight_bit_data_or_control_in[4:0] == 5'h1D) // 29
| (eight_bit_data_or_control_in[4:0] == 5'h1E) // 30
)
d455 2
a456 1
) );
d467 1
a467 1
detected_invalid_8b_10b_sequence,
d474 1
a474 1
output detected_invalid_8b_10b_sequence;
a487 73
//
// As a reminder, this is the list of valid codes. These codes need to
// be decoded into the 8-bit data, into an indication that a control
// data is being sent, and into an indication that an error is detected.
//
// TABLE I 5B/6B ENCODING (NOTE LSB TO LEFT)
// NAME ABCDE K D-1 abcdei DO ALTERNATE
// ______________________________________
// D.0 00000 0 + 011000 - 100111
// D.1 10000 0 + 100010 - 011101 !
// D.2 01000 0 + 010010 - 101101 !
// D.3 11000 0 x 110001 0 !
// D.4 00100 0 + 001010 - 110101 !
// D.5 10100 0 x 101001 0 !
// D.6 01100 0 x 011001 0 !
// D.7 11100 0 - 111000 0 000111 !
// D.8 00010 0 + 000110 - 111001 !
// D.9 10010 0 x 100101 0 !
// D.10 01010 0 x 010101 0 !
// D.11 11010 0 x 110100 0 !
// D.12 00110 0 x 001101 0 !
// D.13 10110 0 x 101100 0 !
// D.14 01110 0 x 011100 0 !
// D.15 11110 0 + 101000 - 010111
// D.16 00001 0 - 011011 + 100100
// D.17 10001 0 x 100011 0 !
// D.18 01001 0 x 010011 0 !
// D.19 11001 0 x 110010 0 !
// D.20 00101 0 x 001011 0 !
// D.21 10101 0 x 101010 0 !
// D.22 01101 0 x 011010 0 !
// D.23 11101 x - 111010 + 000101 !
// D.24 00011 0 + 001100 - 110011
// D.25 10011 0 x 100110 0 !
// D.26 01011 0 x 010110 0 !
// D.27 11011 x - 110110 + 001001 !
// D.28 00111 0 x 001110 0 !
// D.29 10111 x - 101110 + 010001 !
// D.30 01111 x - 011110 + 100001 !
// D.31 11111 0 - 101011 + 010100
//
// K.23 11101 x - 111010 + 000101 !
// K.27 11011 x - 110110 + 001001 !
// K.28 00111 1 - 001111 + 110000 !
// K.29 10111 x - 101110 + 010001 !
// K.30 01111 x - 011110 + 100001 !
//
// TABLE II 3B/4B ENCODING (NOTE LSB TO LEFT)
// NAME FGH K D-1 fghj DO ALTERNATE
// ______________________________________
// D.x.0 000 x + 0100 - 1011
// D.x.1 100 0 x 1001 0 !
// D.x.2 010 0 x 0101 0 !
// D.x.3 110 x - 1100 0 0011 !
// D.x.4 001 x + 0010 - 1101 !
// D.x.5 101 0 x 1010 0 !
// D.x.6 011 0 x 0110 0 !
// D.x.P7 111 0 - 1110 + 0001 ! Primary
// D.x.A7 111 x - 0111 + 1000 Alternate
//
// K.28.0 000 x + 0100 - 1011
// K.28.1 100 1 + 1001 0 0110 ! Singular Comma
// K.28.2 010 1 + 0101 0 1010 !
// K.28.3 110 x - 1100 0 0011 !
// K.28.4 001 x + 0010 - 1101 !
// K.28.5 101 1 + 1010 0 0101 ! Singular Comma
// K.28.6 011 1 + 0110 0 1001 !
// K.28.7 111 x - 0111 + 1000 Singular Comma
//
// K.23.7 111 x - 0111 + 1000
// K.27.7 111 x - 0111 + 1000
// K.29.7 111 x - 0111 + 1000
// K.30.7 111 x - 0111 + 1000
d492 1
a492 1
// Calculate the values for the 6 -> 5 encoding
d501 2
a502 1
a505 3
wire [2:0] LSB_bottom_4_Population = {1'b0, LSB_02_Population[1:0]}
+ {2'b00, ten_bit_encoded_data_in[3]};
d516 6
a521 6
wire Invert_Before_Use = ( (ten_bit_encoded_data_in[5:4] == 2'b10)
& ( (LSB_bottom_4_Population[2:0] == 3'h1)
| (LSB_bottom_4_Population[2:0] == 3'h3) )
)
| (ten_bit_encoded_data_in[5:0] == 6'b111000) // LSB to right
| (ten_bit_encoded_data_in[5:0] == 6'b000011);
d539 10
d559 1
a559 1
wire [3:0] LSB_XOR_Term = {4{Invert_Before_Use}} // invert all signals with alternate values
d579 20
a598 1
// Calculate the values for the 6 -> 5 encoding
d600 3
a602 2
wire MSB_detected_0_value = (ten_bit_encoded_data_in[9:6] == 4'b0010)
| (ten_bit_encoded_data_in[9:6] == 4'b1101);
d604 2
a605 2
wire detected_alternate_encoding = (ten_bit_encoded_data_in[9:6] == 4'b0111)
| (ten_bit_encoded_data_in[9:6] == 4'b1000);
d607 2
a608 3
assign decoded_data[5] = ten_bit_encoded_data_in[6] | detected_alternate_encoding;
assign decoded_data[6] = ten_bit_encoded_data_in[7] & ~MSB_detected_0_value;
assign decoded_data[7] = ten_bit_encoded_data_in[8] | detected_alternate_encoding;
d610 5
a614 1
// Detect invalid code values.
d616 1
a616 18
// From the table in the encode function, we see that the following "abcdei"
// values are illegal: (NOTE LSB TO LEFT)
//
// 000000 (population 0)
// 100000 010000 001000 000100 000010 000001 (population 1)
// 111100 000011 (could result in unintended run of 5 identical values)
// 111110 111101 111011 110111 101111 011111 (population 5)
// 111111 (population 6)
//
// We see that the following "fghj" values are illegal: (NOTE LSB TO LEFT)
//
// 0000, 1111 (populations 0 and 4)
//
// We know that singular commas can only contain a string of 5 like values
// at "c=d=e=i=f", so
//
// It is hard to discover which other combinations are invalid. So I write
// a program below to let me discover all invalid combinations.
d618 3
d623 11
d644 5
a648 1
Running_Disparity <= Running_Disparity;
d652 71
d728 1
a728 2
// always @@(posedge clk)
always @@(decoded_data)
d739 4
a742 3
output_is_control <= 1'b0;
invalid_encoded_data <= 1'b0;
a744 20
// synopsys translate_off
initial
begin
/*
if (NUM_BITS < 2)
begin
$display ("*** Exiting because %m bin_to_grey_code Number of bits %d < 2",
NUM_BITS);
$finish;
end
if (NUM_BITS > 16)
begin
$display ("*** Exiting because %m bin_to_grey_code Number of bits %d > 16",
NUM_BITS);
$finish;
end
*/
end
// synopsys translate_on
d755 1
d761 1
a761 1
wire detected_invalid_8b_10b_sequence;
d765 27
a791 1
initial
d793 11
a803 3
#1; clk = 1'b0; reset = 1'b1;
#1; clk = 1'b1; reset = 1'b1;
#1; clk = 1'b0; reset = 1'b0;
d806 8
a813 1
for (test_data = 9'h000; test_data < 9'h020; test_data = test_data + 9'h001)
d815 3
a817 4
eight_bit_data_or_control_in[7:0] = test_data[7:0];
# 1; $display ("test data, result %x %x %b %b %x %x %b %b",
eight_bit_data_or_control_in[7:5], eight_bit_data_or_control_in[4:0],
ten_bit_encoded_data_out[9:6], ten_bit_encoded_data_out[5:0],
d819 1
a819 1
output_is_control, detected_invalid_8b_10b_sequence);
d821 12
a832 15
/*
input_is_control = 1'b1;
test_data = 23;
# 0; $display ("test data, result %x %b %b %b %b",
test_data[7:0], first_level_encoded_data[5:0],
invert_LSB_if_input_disparity_is_positive,
invert_LSB_if_input_disparity_is_negative,
LSB_toggle_running_disparity);
for (test_data = 27; test_data < 31; test_data = test_data + 9'h001)
begin
# 0; $display ("test data, result %x %b %b %b %b",
test_data[7:0], first_level_encoded_data[5:0],
invert_LSB_if_input_disparity_is_positive,
invert_LSB_if_input_disparity_is_negative,
LSB_toggle_running_disparity);
d835 69
a903 2
input_is_control = 1'b0;
for (test_data = 9'h000 + 28; test_data < 9'h100; test_data = test_data + 9'h020)
d905 1
a905 14
# 0; $display ("test data, result %x %b %b %b %b",
test_data[7:0], first_level_encoded_data[9:6],
invert_MSB_if_LSB_disparity_is_positive,
invert_MSB_if_LSB_disparity_is_negative,
MSB_toggle_running_disparity);
end
input_is_control = 1'b1;
for (test_data = 9'h000 + 28; test_data < 9'h100; test_data = test_data + 9'h020)
begin
# 0; $display ("test data, result %x %b %b %b %b",
test_data[7:0], first_level_encoded_data[9:6],
invert_MSB_if_LSB_disparity_is_positive,
invert_MSB_if_LSB_disparity_is_negative,
MSB_toggle_running_disparity);
d907 6
a912 1
*/
d918 1
d929 1
a929 1
.detected_invalid_8b_10b_sequence (detected_invalid_8b_10b_sequence),
a931 1
d939 5
d1151 1
a1151 1
// Get rid of patterns which use D.7.y with the wrong disparity.
d1160 1
a1160 1
// Get rid of patterns which use D.x.3 with the wrong disparity.
d1171 10
a1180 2
// Get rid of non-control codes which use alternate encoding inappropriately.
// These are all the data items except 23, 27, 29, and 39 which do not end in
d1186 8
a1193 1
& ((i[5:4] == 2'b01) | (i[5:4] == 2'b10)))
d1197 24
a1223 1
end
d1225 12
a1236 3
// Get rid of case when D.x.3 and D.7.y are used together as D.7.3
valid[10'b111000_0011] = 1'b1;
valid[10'b000111_1100] = 1'b1;
d1238 11
a1248 32
// Get rid of case where LSB has 3 bits set, input disparity makes primary
// or alternate code impossible.
invalid[10'b110100_0111] = 1'b1; // negative in 11
invalid[10'b110100_0001] = 1'b1; // positive in 11
invalid[10'b101100_0111] = 1'b1; // negative in 13
invalid[10'b101100_0001] = 1'b1; // positive in 13
invalid[10'b011100_0111] = 1'b1; // negative in 14
invalid[10'b011100_0001] = 1'b1; // positive in 14
invalid[10'b100011_1110] = 1'b1; // negative in 17
invalid[10'b100011_1000] = 1'b1; // positive in 17
invalid[10'b010011_1110] = 1'b1; // negative in 18
invalid[10'b010011_1000] = 1'b1; // positive in 18
invalid[10'b001011_1110] = 1'b1; // negative in 20
invalid[10'b001011_1000] = 1'b1; // positive in 20
invalid[10'b111000_0111] = 1'b1; // negative in 7
invalid[10'b000111_1000] = 1'b1; // positive in 7
// Get rid of case where LSB has 2 or 4 bits set, and choice of primary
// or alternate code makes the other code impossible.
invalid[10'b001100_0111] = 1'b1; // negative 24
invalid[10'b110011_1000] = 1'b1; // positive 24
invalid[10'b010100_0111] = 1'b1; // negative 31
invalid[10'b101011_1000] = 1'b1; // positive 31
invalid[10'b101000_0111] = 1'b1; // negative 15
invalid[10'b010111_1000] = 1'b1; // positive 15
invalid[10'b011000_0111] = 1'b1; // negative 0
invalid[10'b100111_1000] = 1'b1; // positive 0
invalid[10'b100100_0111] = 1'b1; // negative 16
invalid[10'b011011_1000] = 1'b1; // positive 16
invalid[10'b001111_0001] = 1'b1; // positive K28
invalid[10'b110000_1110] = 1'b1; // negative K28
@
1.1
log
@no message
@
text
@d13 6
d66 1
a66 1
// $Id: encode_8b_10b.v,v 1.7 2001/10/22 12:36:12 Blue Beaver Exp $
d71 6
d238 8
a245 1
// Calculate the values for the 3 -> 4 encoding
d247 2
a248 3
// Notice that the bottom bit of the encoded LSB data is the same as
// the input LSB data.
assign first_level_encoded_data[0] = eight_bit_data_or_control_in[0];
d254 8
a261 2
// There are 3 exceptions to this in the LSB. Decode these.
wire LSB_all_zero = (eight_bit_data_or_control_in[3:0] == 4'h0);
d263 5
a267 1
wire LSB_all_one = (eight_bit_data_or_control_in[3:0] == 4'hF);
a282 17
wire LSB_contains_one_one = (eight_bit_data_or_control_in[3:0] == 4'h1)
| (eight_bit_data_or_control_in[3:0] == 4'h2)
| (eight_bit_data_or_control_in[3:0] == 4'h4)
| (eight_bit_data_or_control_in[3:0] == 4'h8);
wire LSB_contains_two_ones = (eight_bit_data_or_control_in[3:0] == 4'h3)
| (eight_bit_data_or_control_in[3:0] == 4'h5)
| (eight_bit_data_or_control_in[3:0] == 4'h9)
| (eight_bit_data_or_control_in[3:0] == 4'h6)
| (eight_bit_data_or_control_in[3:0] == 4'hA)
| (eight_bit_data_or_control_in[3:0] == 4'hC);
wire LSB_contains_three_ones = (eight_bit_data_or_control_in[3:0] == 4'h7) // 23
| (eight_bit_data_or_control_in[3:0] == 4'hB) // 27
| (eight_bit_data_or_control_in[3:0] == 4'hD) // 29
| (eight_bit_data_or_control_in[3:0] == 4'hE); // 30
a287 1
wire LSB_is_28 = (eight_bit_data_or_control_in[4:0] == 5'h1C); // 28
d289 3
a291 3
assign first_level_encoded_data[4] = ( LSB_contains_one_one
| eight_bit_data_or_control_in[4])
& ~LSB_is_24;
d294 4
a297 4
(LSB_contains_two_ones & ~eight_bit_data_or_control_in[4])
| ( ( LSB_contains_other_i | LSB_all_one)
& eight_bit_data_or_control_in[4])
| (input_is_control & LSB_is_28);
d308 4
a311 4
( LSB_all_zero
| LSB_contains_one_one
| LSB_all_one)
& (eight_bit_data_or_control_in[4] == 1'b0);
d314 1
a314 2
LSB_term_has_positive_disparity
| (eight_bit_data_or_control_in[4:0] == 5'h07); // 7
d317 1
a317 2
LSB_term_has_negative_disparity
| (eight_bit_data_or_control_in[3:0] == 4'h8); // 24
d335 14
a348 13
wire use_alternate_encoding = ( input_is_control
| ( (Running_Disparity == 1'b0)
& ( (eight_bit_data_or_control_in[4:0] == 5'h11) // 17
| (eight_bit_data_or_control_in[4:0] == 5'h12) // 18
| (eight_bit_data_or_control_in[4:0] == 5'h14) // 20
))
| ( (Running_Disparity == 1'b1)
& ( (eight_bit_data_or_control_in[4:0] == 5'h0B) // 11
| (eight_bit_data_or_control_in[4:0] == 5'h0D) // 13
| (eight_bit_data_or_control_in[4:0] == 5'h0E) // 14
))
)
& (eight_bit_data_or_control_in[7:5] == 3'h7);
d424 2
a425 1
always @@(posedge clk)
a448 20
// synopsys translate_off
initial
begin
/*
if (NUM_BITS < 2)
begin
$display ("*** Exiting because %m bin_to_grey_code Number of bits %d < 2",
NUM_BITS);
$finish;
end
if (NUM_BITS > 16)
begin
$display ("*** Exiting because %m bin_to_grey_code Number of bits %d > 16",
NUM_BITS);
$finish;
end
*/
end
// synopsys translate_on
d457 1
a457 1
invalid_encoded_data,
d464 1
a464 1
output invalid_encoded_data;
d478 76
d555 3
d566 1
a566 1
+ {1'b0, LSB_35_Population[1:0]};
d568 2
a569 4
wire [1:0] MSB_67_Population = ten_bit_encoded_data_in[6] // full adder
+ ten_bit_encoded_data_in[7];
wire [1:0] MSB_89_Population = ten_bit_encoded_data_in[8] // full adder
+ ten_bit_encoded_data_in[9];
d571 76
a646 2
wire [2:0] MSB_Population = {1'b0, MSB_67_Population[1:0]} // allowed: 1, 2, 3
+ {1'b0, MSB_89_Population[1:0]};
d663 3
a666 4
// The Xilinx Ap note says these are errors:
// too large or small disparity, a=b=c=d, P13e'i', p31e'i, f=g=h=j,
// e=i=f=g=h, i!=e=g=h=j, (e=i!=g=h=j)*(c=d=e)', P31ei'g'h'j', P13e'ighj,
// non-alternating disparity, data must follow rules
d688 2
a689 1
always @@(posedge clk)
d699 1
a699 1
eight_bit_data_or_control_out[7:0] <= 8'h00;
d705 19
d727 1
a727 1
// `define TEST_8B_10B
d733 1
a733 4
// development code
wire [7:0] eight_bit_data_or_control_in = test_data[7:0];
wire [9:0] first_level_encoded_data;
d735 2
d738 3
a740 87
wire LSB_all_zero = (eight_bit_data_or_control_in[3:0] == 4'h0);
wire LSB_is_24 = (eight_bit_data_or_control_in[4:0] == 5'h18);
wire LSB_all_one = (eight_bit_data_or_control_in[3:0] == 4'hF);
assign first_level_encoded_data[0] = eight_bit_data_or_control_in[0];
assign first_level_encoded_data[1] = ( eight_bit_data_or_control_in[1]
& ~LSB_all_one)
| LSB_all_zero;
assign first_level_encoded_data[2] = eight_bit_data_or_control_in[2]
| LSB_all_zero
| LSB_is_24;
assign first_level_encoded_data[3] = ( eight_bit_data_or_control_in[3]
& ~LSB_all_one);
wire LSB_contains_one_one = (eight_bit_data_or_control_in[3:0] == 4'h1)
| (eight_bit_data_or_control_in[3:0] == 4'h2)
| (eight_bit_data_or_control_in[3:0] == 4'h4)
| (eight_bit_data_or_control_in[3:0] == 4'h8);
wire LSB_contains_two_ones = (eight_bit_data_or_control_in[3:0] == 4'h3)
| (eight_bit_data_or_control_in[3:0] == 4'h5)
| (eight_bit_data_or_control_in[3:0] == 4'h9)
| (eight_bit_data_or_control_in[3:0] == 4'h6)
| (eight_bit_data_or_control_in[3:0] == 4'hA)
| (eight_bit_data_or_control_in[3:0] == 4'hC);
wire LSB_contains_three_ones = (eight_bit_data_or_control_in[3:0] == 4'h7) // 23
| (eight_bit_data_or_control_in[3:0] == 4'hB) // 27
| (eight_bit_data_or_control_in[3:0] == 4'hD) // 29
| (eight_bit_data_or_control_in[3:0] == 4'hE); // 30
wire LSB_contains_other_i = (eight_bit_data_or_control_in[3:0] == 4'h0)
| (eight_bit_data_or_control_in[3:0] == 4'h1)
| (eight_bit_data_or_control_in[3:0] == 4'h2)
| (eight_bit_data_or_control_in[3:0] == 4'h4);
wire LSB_is_28 = (eight_bit_data_or_control_in[4:0] == 5'h1C); // 28
assign first_level_encoded_data[4] = ( LSB_contains_one_one
| eight_bit_data_or_control_in[4])
& ~LSB_is_24;
assign first_level_encoded_data[5] =
(LSB_contains_two_ones & ~eight_bit_data_or_control_in[4])
| ( ( LSB_contains_other_i | LSB_all_one)
& eight_bit_data_or_control_in[4])
| (input_is_control & LSB_is_28);
wire LSB_term_has_positive_disparity =
| ( ( LSB_all_zero
| LSB_contains_three_ones
| LSB_all_one)
& (eight_bit_data_or_control_in[4] == 1'b1))
| input_is_control;
wire LSB_term_has_negative_disparity =
( LSB_all_zero
| LSB_contains_one_one
| LSB_all_one)
& (eight_bit_data_or_control_in[4] == 1'b0);
wire invert_LSB_if_input_disparity_is_positive =
LSB_term_has_positive_disparity
| (eight_bit_data_or_control_in[4:0] == 5'h07); // 7
wire invert_LSB_if_input_disparity_is_negative =
LSB_term_has_negative_disparity
| (eight_bit_data_or_control_in[3:0] == 4'h8); // 24
wire LSB_toggle_running_disparity =
LSB_term_has_positive_disparity
| invert_LSB_if_input_disparity_is_negative;
wire use_alternate_encoding = ( input_is_control
| (1'b0) ) // NOTE WRONG
& (eight_bit_data_or_control_in[7:5] == 3'h7);
// The alternate Data encoding D.x.A7 is used in the case
// that e = i = 1 and negative running disparity,
// or e = i = 0 and positive running disparity,
// or a Control signal is being sent encoding 7 in the MSB.
assign first_level_encoded_data[6] = eight_bit_data_or_control_in[5]
& ~use_alternate_encoding;
// The second bit of the MSB is a pass-through except when the input
// is all 0's.
d742 1
a742 35
wire MSB_all_zero = (eight_bit_data_or_control_in[7] == 1'h0)
& (eight_bit_data_or_control_in[5] == 1'h0);
assign first_level_encoded_data[7] = eight_bit_data_or_control_in[6]
| MSB_all_zero;
// Notice that the top bit of the encoded MSB data is the same as
// the input MSB data.
assign first_level_encoded_data[8] = eight_bit_data_or_control_in[7];
// Bit "j" is chosen to guarantee that there are enough transitions,
// and to control the disparity caused by each pattern.
assign first_level_encoded_data[9] =
(eight_bit_data_or_control_in[7:5] == 3'h1)
| (eight_bit_data_or_control_in[7:5] == 3'h2)
| use_alternate_encoding;
wire invert_MSB_if_LSB_disparity_is_positive =
(eight_bit_data_or_control_in[7:5] == 3'h3)
| (eight_bit_data_or_control_in[7:5] == 3'h7);
wire invert_MSB_if_LSB_disparity_is_negative =
(eight_bit_data_or_control_in[7:5] == 3'h0)
| (eight_bit_data_or_control_in[7:5] == 3'h4)
| ( input_is_control
& ( (eight_bit_data_or_control_in[7:5] == 3'h1)
| (eight_bit_data_or_control_in[7:5] == 3'h2)
| (eight_bit_data_or_control_in[7:5] == 3'h5)
| (eight_bit_data_or_control_in[7:5] == 3'h6) ));
wire MSB_toggle_running_disparity =
(eight_bit_data_or_control_in[7:5] == 3'h0)
| (eight_bit_data_or_control_in[7:5] == 3'h4)
| (eight_bit_data_or_control_in[7:5] == 3'h7);
d746 4
d753 6
a758 5
# 0; $display ("test data, result %x %b %b %b %b %b", test_data[7:0],
first_level_encoded_data[9:6], first_level_encoded_data[5:0],
invert_LSB_if_input_disparity_is_positive,
invert_LSB_if_input_disparity_is_negative,
LSB_toggle_running_disparity);
d760 1
a760 1
d795 1
a797 2
wire [9:0] ten_bit_encoded_data_out;
a806 4
wire [9:0] ten_bit_encoded_data_in;
wire [7:0] eight_bit_data_or_control_out;
d808 1
a808 1
.ten_bit_encoded_data_in (ten_bit_encoded_data_in[9:0]),
d811 1
a811 1
.invalid_encoded_data (invalid_encoded_data),
d819 2
d825 2
a826 1
reg [4095:0] mask; // storage
d832 1
a832 1
mask[full_addr[9:0]] = 1'b1;
d836 1
a836 1
task test_both;
d852 1
a852 1
task test_positive;
d865 1
a865 1
task test_negative;
d878 1
a878 1
task test_all;
d880 3
a882 3
test_positive;
test_negative;
test_both;
d886 1
a886 1
task test;
d895 1
a895 1
test_all;
d899 2
a900 2
test_positive;
test_both;
d904 2
a905 2
test_negative;
test_both;
d916 2
a917 1
mask[i[9:0]] = 1'b0;
d920 78
a997 49
// Mark bits which are parts of valid codes
test (6'b110001, 0);
test (6'b101001, 0);
test (6'b011001, 0);
test (6'b100101, 0);
test (6'b010101, 0);
test (6'b110100, 0);
test (6'b001101, 0);
test (6'b101100, 0);
test (6'b011100, 0);
test (6'b100011, 0);
test (6'b010011, 0);
test (6'b110010, 0);
test (6'b001011, 0);
test (6'b101010, 0);
test (6'b011010, 0);
test (6'b100110, 0);
test (6'b010110, 0);
test (6'b001110, 0);
test (6'b011000, -1);
test (6'b100010, -1);
test (6'b010010, -1);
test (6'b001010, -1);
test (6'b111000, -1);
test (6'b000110, -1);
test (6'b101000, -1);
test (6'b100100, -1);
test (6'b000101, -1);
test (6'b001100, -1);
test (6'b001001, -1);
test (6'b010001, -1);
test (6'b100001, -1);
test (6'b010100, -1);
test (6'b100111, +1);
test (6'b011101, +1);
test (6'b101101, +1);
test (6'b110101, +1);
test (6'b000111, +1);
test (6'b111001, +1);
test (6'b010111, +1);
test (6'b011011, +1);
test (6'b111010, +1);
test (6'b110011, +1);
test (6'b110110, +1);
test (6'b101110, +1);
test (6'b011110, +1);
test (6'b101011, +1);
d1004 1
a1004 1
mask[i[9:0]] = 1'b1;
d1008 1
a1008 1
mask[i[9:0]] = 1'b1;
d1013 1
a1013 1
mask[i[9:0]] = 1'b1;
d1018 1
a1018 1
mask[i[9:0]] = 1'b1;
d1022 1
a1022 1
mask[i[9:0]] = 1'b1;
d1027 1
a1027 1
mask[i[9:0]] = 1'b1;
d1032 1
a1032 1
mask[i[9:0]] = 1'b1;
d1036 1
a1036 1
mask[i[9:0]] = 1'b1;
d1042 1
a1042 1
mask[i[9:0]] = 1'b1;
d1047 1
a1047 1
mask[i[9:0]] = 1'b1;
d1060 1
a1060 1
mask[i[9:0]] = 1'b1;
d1066 2
a1067 2
mask[10'b111000_0011] = 1'b1;
mask[10'b000111_1100] = 1'b1;
d1071 12
a1082 12
mask[10'b110100_0111] = 1'b1; // negative in 11
mask[10'b110100_0001] = 1'b1; // positive in 11
mask[10'b101100_0111] = 1'b1; // negative in 13
mask[10'b101100_0001] = 1'b1; // positive in 13
mask[10'b011100_0111] = 1'b1; // negative in 14
mask[10'b011100_0001] = 1'b1; // positive in 14
mask[10'b100011_1110] = 1'b1; // negative in 17
mask[10'b100011_1000] = 1'b1; // positive in 17
mask[10'b010011_1110] = 1'b1; // negative in 18
mask[10'b010011_1000] = 1'b1; // positive in 18
mask[10'b001011_1110] = 1'b1; // negative in 20
mask[10'b001011_1000] = 1'b1; // positive in 20
d1084 2
a1085 2
mask[10'b111000_0111] = 1'b1; // negative in 7
mask[10'b000111_1000] = 1'b1; // positive in 7
d1089 12
a1100 51
mask[10'b001100_0111] = 1'b1; // negative 24
mask[10'b110011_1000] = 1'b1; // positive 24
// mask[10'b001110_0111] = 1'b1; // negative 28
// mask[10'b001110_1000] = 1'b1; // positive 28
mask[10'b010100_0111] = 1'b1; // negative 31
mask[10'b101011_1000] = 1'b1; // positive 31
mask[10'b101000_0111] = 1'b1; // negative 15
mask[10'b010111_1000] = 1'b1; // positive 15
mask[10'b011000_0111] = 1'b1; // negative 0
mask[10'b100111_1000] = 1'b1; // positive 0
mask[10'b100100_0111] = 1'b1; // negative 16
mask[10'b011011_1000] = 1'b1; // positive 16
mask[10'b001111_0001] = 1'b1; // positive K28
mask[10'b110000_1110] = 1'b1; // negative K28
// get rid of the control codes.
mask[10'b111010_1000] = 1'b1;
mask[10'b110110_1000] = 1'b1;
mask[10'b101110_1000] = 1'b1;
mask[10'b011110_1000] = 1'b1;
mask[10'b001111_0100] = 1'b1;
mask[10'b001111_1001] = 1'b1;
mask[10'b001111_0101] = 1'b1;
mask[10'b001111_0011] = 1'b1;
mask[10'b001111_0010] = 1'b1;
mask[10'b001111_1010] = 1'b1;
mask[10'b001111_0110] = 1'b1;
mask[10'b001111_1000] = 1'b1;
mask[~10'b111010_1000] = 1'b1;
mask[~10'b110110_1000] = 1'b1;
mask[~10'b101110_1000] = 1'b1;
mask[~10'b011110_1000] = 1'b1;
mask[~10'b001111_0100] = 1'b1;
mask[~10'b001111_1001] = 1'b1;
mask[~10'b001111_0101] = 1'b1;
mask[~10'b001111_0011] = 1'b1;
mask[~10'b001111_0010] = 1'b1;
mask[~10'b001111_1010] = 1'b1;
mask[~10'b001111_0110] = 1'b1;
mask[~10'b001111_1000] = 1'b1;
// The Xilinx Ap note says these are errors:
// too large or small disparity, a=b=c=d, P13e'i', p31e'i, f=g=h=j,
// e=i=f=g=h, i!=e=g=h=j, (e=i!=g=h=j)*(c=d=e)', P31ei'g'h'j', P13e'ighj,
// non-alternating disparity, data must follow rules
d1105 1
a1105 1
if (mask[i[9:0]] !== 1'b1)
d1109 4
d1117 1
a1117 1
@