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 @