OpenCores
URL https://opencores.org/ocsvn/common/common/trunk

Subversion Repositories common

[/] [common/] [trunk/] [encode_8b_10b.v] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 bbeaver
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
//// encode_8b_10b #(N), decode_10b_8b #(N)                       ////
4
////                                                              ////
5
//// This file is part of the general opencores effort.           ////
6
//// <http://www.opencores.org/cores/misc/>                       ////
7
////                                                              ////
8
//// Module Description:                                          ////
9
////    Example of how to convert 8B data to 10B data.            ////
10
////    Example of how to convert 10B data to 8B data.            ////
11
////                                                              ////
12
//// NOTE:                                                        ////
13 19 bbeaver
////    The IBM Patent grew up in a world where the Least         ////
14
////    Significant Bit of a word was written to the Left.        ////
15
////    These modules use the LSB as Bit 0, and it will           ////
16
////    typically be written as the Rightmost bit in a field.     ////
17
////                                                              ////
18
//// NOTE:                                                        ////
19 18 bbeaver
////    These modules are based on information contained in       ////
20
////    "Implementing an 8B/10B Encoder/Decoder for Gigabit       ////
21
////     Ethernet" by Daniel Elftmann and Jing Hua Ma of Altera.  ////
22
////    The paper was given in the International IC Tiapei        ////
23
////    conferance in 1999.                                       ////
24
////                                                              ////
25
////    A second source of information is XAPP336 titled "Design  ////
26
////    of a 16B/20B Encoder/Decoder using a Coolrunner CPLD"     ////
27
////    found on the Xilinx web sire www.xilinx.com               ////
28
////                                                              ////
29
////    The best article describing this is at wildpackets.com    ////
30
////    http://www.wildpackets.com/compendium/GB/L1-GbEn.html     ////
31
////                                                              ////
32
////    Finally, this is covered in US patent 4,665,517.          ////
33
////    Unfortunately the US Patent Office online copy has        ////
34
////    missing figures and the tables are un-readable.           ////
35
////                                                              ////
36
//// Author(s):                                                   ////
37
//// - Anonymous                                                  ////
38
////                                                              ////
39
//////////////////////////////////////////////////////////////////////
40
////                                                              ////
41
//// Copyright (C) 2000 Anonymous and OPENCORES.ORG               ////
42
////                                                              ////
43
//// This source file may be used and distributed without         ////
44
//// restriction provided that this copyright statement is not    ////
45
//// removed from the file and that any derivative work contains  ////
46
//// the original copyright notice and the associated disclaimer. ////
47
////                                                              ////
48
//// This source file is free software; you can redistribute it   ////
49
//// and/or modify it under the terms of the GNU Lesser General   ////
50
//// Public License as published by the Free Software Foundation; ////
51
//// either version 2.1 of the License, or (at your option) any   ////
52
//// later version.                                               ////
53
////                                                              ////
54
//// This source is distributed in the hope that it will be       ////
55
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
56
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
57
//// PURPOSE. See the GNU Lesser General Public License for more  ////
58
//// details.                                                     ////
59
////                                                              ////
60
//// You should have received a copy of the GNU Lesser General    ////
61
//// Public License along with this source; if not, download it   ////
62
//// from <http://www.opencores.org/lgpl.shtml>                   ////
63
////                                                              ////
64
//////////////////////////////////////////////////////////////////////
65
//
66 37 bbeaver
// $Id: encode_8b_10b.v,v 1.6 2001-11-29 09:22:08 bbeaver Exp $
67 18 bbeaver
//
68
// CVS Revision History
69
//
70
// $Log: not supported by cvs2svn $
71 37 bbeaver
// Revision 1.19  2001/11/29 09:31:11  Blue Beaver
72
// no message
73
//
74 24 bbeaver
// Revision 1.18  2001/10/26 10:39:43  Blue Beaver
75
// no message
76
//
77
// Revision 1.17  2001/10/26 10:38:05  Blue Beaver
78
// no message
79
//
80
// Revision 1.16  2001/10/25 11:43:03  Blue Beaver
81
// no message
82
//
83 23 bbeaver
// Revision 1.14  2001/10/25 11:33:51  Blue Beaver
84
// no message
85
//
86 22 bbeaver
// Revision 1.13  2001/10/24 11:38:02  Blue Beaver
87
// no message
88
//
89
// Revision 1.12  2001/10/24 09:47:40  Blue Beaver
90
// no message
91
//
92
// Revision 1.11  2001/10/24 08:49:02  Blue Beaver
93
// no message
94
//
95
// Revision 1.10  2001/10/24 07:28:08  Blue Beaver
96
// no message
97
//
98 19 bbeaver
// Revision 1.9  2001/10/23 10:34:50  Blue Beaver
99
// no message
100
//
101
// Revision 1.8  2001/10/23 08:12:37  Blue Beaver
102
// no message
103
//
104 18 bbeaver
// Revision 1.7  2001/10/22 12:36:12  Blue Beaver
105
// no message
106
//
107
// Revision 1.6  2001/10/22 11:54:58  Blue Beaver
108
// no message
109
//
110
// Revision 1.5  2001/10/21 11:37:28  Blue Beaver
111
// no message
112
//
113
// Revision 1.4  2001/10/21 10:17:34  Blue Beaver
114
// no message
115
//
116
// Revision 1.3  2001/10/21 03:40:52  Blue Beaver
117
// no message
118
//
119
// Revision 1.2  2001/10/21 02:27:39  Blue Beaver
120
// no message
121
//
122
// Revision 1.1  2001/10/21 01:36:14  Blue Beaver
123
// no message
124
//
125
//
126
//
127
 
128
`timescale 1ns/1ps
129
 
130
 
131
// These are the codes which are valid to use as control codes.
132
// I believe that they have names, but I don't know them.
133
// Note K_28_1, K_28_5, and K_28_7 contain Singular Commas.
134
`define K_28_0 8'b000_11100
135
`define K_28_1 8'b001_11100
136
`define K_28_2 8'b010_11100
137
`define K_28_3 8'b011_11100
138
`define K_28_4 8'b100_11100
139
`define K_28_5 8'b101_11100
140
`define K_28_6 8'b110_11100
141
`define K_28_7 8'b111_11100
142
 
143
`define K_23_7 8'b111_10111
144
`define K_27_7 8'b111_11011
145
`define K_29_7 8'b111_11101
146
`define K_30_7 8'b111_11110
147
 
148
// Convert 8-bit binary or 8-bit control code to 10-bit code
149
 
150
module encode_8b_10b (
151
  eight_bit_data_or_control_in,
152
  input_is_control,
153 22 bbeaver
  mess_up_link_disparity,
154 18 bbeaver
  ten_bit_encoded_data_out,
155
  invalid_control,
156
  clk,
157
  reset
158
);
159
 
160
  input  [7:0] eight_bit_data_or_control_in;
161
  input   input_is_control;
162 22 bbeaver
  input   mess_up_link_disparity;
163 18 bbeaver
  output [9:0] ten_bit_encoded_data_out;
164
  output  invalid_control;
165
  input   clk, reset;
166
 
167
// Data is treated as 2 fields.  The 3 MSB bits are treated as 1 field, and
168
//   the 5 LSB bits are treated as another field.
169
// The 5 LSB bits are encoded as 6 bits.  The 3 MSB bits are encoded as 4 bits.
170
// The encodings are chosen so that the 10 bits together have either
171
//   1) 5 1's and 5 0's,
172
//   2) 4 1's and 6 0's,
173
//   3  6 1's and 4 0's
174
// There are alternative encodings for the cases that the number of 1's and 0's
175
//   are not balanced.  The 8B/10B encoder keeps track of the running disparity
176
//   between the number of 1's and 0's, and uses alternate encodings to keep
177
//   the serial signal balanced with no disparity on average.
178
//
179
//  TABLE I 5B/6B ENCODING  (NOTE LSB TO LEFT)
180
//  NAME    ABCDE    K     D-1  abcdei  DO   ALTERNATE
181
//  ______________________________________
182
//  D.0     00000    0     +    011000  -    100111
183
//  D.1     10000    0     +    100010  -    011101   !
184
//  D.2     01000    0     +    010010  -    101101   !
185
//  D.3     11000    0     x    110001  0             !
186
//  D.4     00100    0     +    001010  -    110101   !
187
//  D.5     10100    0     x    101001  0             !
188
//  D.6     01100    0     x    011001  0             !
189
//  D.7     11100    0     -    111000  0    000111   !
190
//  D.8     00010    0     +    000110  -    111001   !
191
//  D.9     10010    0     x    100101  0             !
192
//  D.10    01010    0     x    010101  0             !
193
//  D.11    11010    0     x    110100  0             !
194
//  D.12    00110    0     x    001101  0             !
195
//  D.13    10110    0     x    101100  0             !
196
//  D.14    01110    0     x    011100  0             !
197
//  D.15    11110    0     +    101000  -    010111
198
//  D.16    00001    0     -    011011  +    100100
199
//  D.17    10001    0     x    100011  0             !
200
//  D.18    01001    0     x    010011  0             !
201
//  D.19    11001    0     x    110010  0             !
202
//  D.20    00101    0     x    001011  0             !
203
//  D.21    10101    0     x    101010  0             !
204
//  D.22    01101    0     x    011010  0             !
205
//  D.23    11101    x     -    111010  +    000101   !
206
//  D.24    00011    0     +    001100  -    110011
207
//  D.25    10011    0     x    100110  0             !
208
//  D.26    01011    0     x    010110  0             !
209
//  D.27    11011    x     -    110110  +    001001   !
210
//  D.28    00111    0     x    001110  0             !
211
//  D.29    10111    x     -    101110  +    010001   !
212
//  D.30    01111    x     -    011110  +    100001   !
213
//  D.31    11111    0     -    101011  +    010100
214
//
215
//  K.23    11101    x     -    111010  +    000101   !
216
//  K.27    11011    x     -    110110  +    001001   !
217
//  K.28    00111    1     -    001111  +    110000   !
218
//  K.29    10111    x     -    101110  +    010001   !
219
//  K.30    01111    x     -    011110  +    100001   !
220
//
221
//  TABLE II 3B/4B ENCODING  (NOTE LSB TO LEFT)
222
//  NAME     FGH     K     D-1   fghj   DO   ALTERNATE
223
//  ______________________________________ 
224
//  D.x.0    000     x     +     0100   -    1011 
225
//  D.x.1    100     0     x     1001   0             !
226
//  D.x.2    010     0     x     0101   0             !
227
//  D.x.3    110     x     -     1100   0    0011     !
228
//  D.x.4    001     x     +     0010   -    1101     !
229
//  D.x.5    101     0     x     1010   0             !
230
//  D.x.6    011     0     x     0110   0             !
231
//  D.x.P7   111     0     -     1110   +    0001     ! Primary
232
//  D.x.A7   111     x     -     0111   +    1000       Alternate
233
//
234
//  K.28.0   000     x     +     0100   -    1011
235
//  K.28.1   100     1     +     1001   0    0110     ! Singular Comma
236
//  K.28.2   010     1     +     0101   0    1010     !
237
//  K.28.3   110     x     -     1100   0    0011     !
238
//  K.28.4   001     x     +     0010   -    1101     !
239
//  K.28.5   101     1     +     1010   0    0101     ! Singular Comma
240
//  K.28.6   011     1     +     0110   0    1001     !
241
//  K.28.7   111     x     -     0111   +    1000       Singular Comma
242
//
243
//  K.23.7   111     x     -     0111   +    1000
244
//  K.27.7   111     x     -     0111   +    1000
245
//  K.29.7   111     x     -     0111   +    1000
246
//  K.30.7   111     x     -     0111   +    1000
247
//
248
// The alternate Data encoding D.x.A7 is used in the case
249
//   that e = i = 1 and negative running disparity,
250
//   or   e = i = 0 and positive running disparity,
251
//   or a Control signal is being sent,
252
//   all while encoding 7 in the MSB.
253
//
254
// This exception to the simple rule guarantees that there
255
//   aren't a run of 5 1's or 5 0's in the first 6 bits
256
//   concatinated with the last 4 bits.
257
//
258
// The special sequence starting at "a" of 2 0's followed by
259
//   5 1's, or 2 1's followed by 5 0's, is called a
260
//   "Singular Comma".
261
// A Singular Comma does not occur in any valid code EXCEPT
262 23 bbeaver
//   K.28.1 or K.28.5 or K.28.7.
263
//
264
// The web says K.28.5 is the Fiber Channel Comma Character.
265
//
266
// NOTE that K.28.7 is a bad comma character, because it
267
//   can be followed by a FALSE comma character when followed
268
//   by any character starting with 2 1's or 0's, like K.11
269
// The false comma character is part in the K.28.7 and part
270
//   in the following data byte.  Bad.
271 37 bbeaver
//
272
// The following info is found in www.wildpackets.com/compendium/GB/L1-GbEn.html,
273
//   in a document headed:
274
// "Gigabit Ethernet is Closely Related to Fibre Channel Technology,
275
//    going back to 1988!"
276
//
277
// 8B-10B characters are described as Dn.m, where n gives the low order
278
//    5 bits in decimal, and m gives the top 3 bits.
279
//
280
// Configuration data is transferred as an alternating sequence of:
281
// (flips disparity: "C1") K28.5/D21.5/Config_reg[7:0]/Config_reg[15:8]
282
// (leaves disparity: "C2") K28.5/D2.2/Config_reg[7:0]/Config_reg[15:8]
283
//
284
// Idle status is transmitted when ther eis nothing else to send.
285
// The link is left in negative disparity.  If it is positive, first
286
// "I1" K28.5/D5.6 is sent, which knocks the displarity to negative
287
// "I2" K28.5/D16.2 is sent repeatitively to maintain the negative disparity
288
//
289
// Start of Packet delimiter "S" K27.7
290
// End of Packet delimiter "T" K29.7
291
// Carrier Extend "R" K23.7
292
//
293
// An End Of Packet consists of either T/R/I or T/R/R
294
// The second is used when a packet follows the previous packet in a burst.
295
// "R" is also sent so that a subsequent "I" follows on an even-numbered
296
//   code boundry.
297
//
298
// Error propagation "V"  K30.7
299
 
300
 
301 18 bbeaver
// Accumulate the new data.  First, calculate ignoring the running disparity;
302
  wire   [9:0] first_level_encoded_data;
303
 
304 19 bbeaver
// Calculate the values for the 5 -> 6 encoding
305 18 bbeaver
 
306 19 bbeaver
// Discover important details about the incoming numbers.
307 22 bbeaver
  wire   [1:0] LSB_02_Population = eight_bit_data_or_control_in[0]  // half adder
308
                                 + eight_bit_data_or_control_in[1];
309
  wire   [1:0] LSB_34_Population = eight_bit_data_or_control_in[2]  // half adder
310
                                 + eight_bit_data_or_control_in[3];
311 19 bbeaver
  wire   [2:0] LSB_Population = {1'b0, LSB_02_Population[1:0]}
312
                              + {1'b0, LSB_34_Population[1:0]};
313
 
314 18 bbeaver
// As can be seen, in many of the LSB encodings the bottom
315
//   4 of the encoded data are identical to the input
316
//   data.  (These are noted with a trailing "!")
317
//
318 19 bbeaver
// There are several exceptions to this in the LSB.  Decode these.
319
  wire    LSB_all_zero = (LSB_Population[2:0] == 3'h0);
320
  wire    LSB_contains_one_one = (LSB_Population[2:0] == 3'h1);
321
  wire    LSB_contains_two_ones = (LSB_Population[2:0] == 3'h2);
322
  wire    LSB_contains_three_ones = (LSB_Population[2:0] == 3'h3);
323
  wire    LSB_all_one  = (LSB_Population[2:0] == 3'h4);
324
 
325
  wire    LSB_is_7     = (eight_bit_data_or_control_in[4:0] == 5'h07);  // 7
326 18 bbeaver
  wire    LSB_is_24    = (eight_bit_data_or_control_in[4:0] == 5'h18);  // 24
327 19 bbeaver
  wire    LSB_is_28    = (eight_bit_data_or_control_in[4:0] == 5'h1C);  // 28
328 22 bbeaver
  wire    LSB_is_23_27_29_30 = (eight_bit_data_or_control_in[4:0] == 5'h17)  // 23
329
                             | (eight_bit_data_or_control_in[4:0] == 5'h1B)  // 27
330
                             | (eight_bit_data_or_control_in[4:0] == 5'h1D)  // 29
331
                             | (eight_bit_data_or_control_in[4:0] == 5'h1E);  // 30
332
  wire    LSB_contains_other_i = (eight_bit_data_or_control_in[3:0] == 4'h0)
333
                               | (eight_bit_data_or_control_in[3:0] == 4'h1)
334
                               | (eight_bit_data_or_control_in[3:0] == 4'h2)
335
                               | (eight_bit_data_or_control_in[3:0] == 4'h4);
336 18 bbeaver
 
337 19 bbeaver
// Notice that the bottom bit of the encoded LSB data is the same as
338
//   the input LSB data.
339
  assign  first_level_encoded_data[0] = eight_bit_data_or_control_in[0];
340
 
341 18 bbeaver
// If the bottom 4 bits are 0s, force 0110 (LSB is the left bit)
342
// If the bottom 5 bits are 24, force 0011 (LSB is the left bit)
343
// If the bottom 4 bits are 1s, force 1010 (LSB is the left bit)
344
  assign  first_level_encoded_data[1] = (   eight_bit_data_or_control_in[1]
345
                                          & ~LSB_all_one)
346
                                      | LSB_all_zero;
347
  assign  first_level_encoded_data[2] = eight_bit_data_or_control_in[2]
348
                                      | LSB_all_zero
349
                                      | LSB_is_24;
350
  assign  first_level_encoded_data[3] = (   eight_bit_data_or_control_in[3]
351
                                          & ~LSB_all_one);
352
 
353
// Bits "e" and "i" are chosen to guarantee that there are enough transitions,
354
//   and to control the disparity caused by each pattern.
355
 
356 19 bbeaver
  assign  first_level_encoded_data[4] =
357
                  (LSB_contains_one_one | eight_bit_data_or_control_in[4])
358
                & ~LSB_is_24;
359 18 bbeaver
 
360
  assign  first_level_encoded_data[5] =
361 19 bbeaver
                  (LSB_contains_two_ones & ~eight_bit_data_or_control_in[4])
362
                | (   (  LSB_contains_other_i | LSB_all_one)
363
                    & eight_bit_data_or_control_in[4])
364
                | (input_is_control & LSB_is_28);
365 18 bbeaver
 
366
// Now calculate the other information needed to produce the LSB output data
367 22 bbeaver
  wire    LSB_code_has_positive_disparity =
368 18 bbeaver
                | (   (   LSB_all_zero
369
                        | LSB_contains_three_ones
370
                        | LSB_all_one)
371 22 bbeaver
                    & (eight_bit_data_or_control_in[4] == 1'b1) )
372
                | (input_is_control & LSB_is_28);
373 18 bbeaver
 
374 22 bbeaver
  wire    LSB_code_has_negative_disparity =
375
                  ( (   LSB_all_zero
376
                      | LSB_contains_one_one
377
                      | LSB_all_one)
378
                    & (eight_bit_data_or_control_in[4] == 1'b0) )
379
                | LSB_is_24;
380 18 bbeaver
 
381
  wire    invert_LSB_if_input_disparity_is_positive =
382 22 bbeaver
                  LSB_code_has_positive_disparity
383
                | LSB_is_7;
384 18 bbeaver
 
385
  wire    invert_LSB_if_input_disparity_is_negative =
386 22 bbeaver
                  LSB_code_has_negative_disparity;
387 18 bbeaver
 
388
  wire    LSB_toggle_running_disparity =
389 22 bbeaver
                  LSB_code_has_positive_disparity
390
                | LSB_code_has_negative_disparity;
391 18 bbeaver
 
392
// Calculate the values for the 3 -> 4 encoding
393
 
394
// An alternate encoding of the MSB for an input of 0x7 is used to
395
//   prevent accidental use of a pattern with 5 0's or 1's in a row.
396
// The alternate Data encoding D.x.A7 is used in the case
397
//   that e = i = 0 and positive running disparity,
398
//   or   e = i = 1 and negative running disparity,
399
//   or a Control signal is being sent,
400
//   all while encoding 7 in the MSB.
401
 
402
  reg     Running_Disparity;  // forward reference
403
 
404 19 bbeaver
  wire    use_alternate_encoding =
405
                  (   input_is_control
406
                    | (   (Running_Disparity == 1'b0)
407
                        & (   (eight_bit_data_or_control_in[4:0] == 5'h11)  // 17
408
                            | (eight_bit_data_or_control_in[4:0] == 5'h12)  // 18
409
                            | (eight_bit_data_or_control_in[4:0] == 5'h14)  // 20
410
                      ))
411
                    | (   (Running_Disparity == 1'b1)
412
                        & (   (eight_bit_data_or_control_in[4:0] == 5'h0B)  // 11
413
                            | (eight_bit_data_or_control_in[4:0] == 5'h0D)  // 13
414
                            | (eight_bit_data_or_control_in[4:0] == 5'h0E)  // 14
415
                      ))
416
                  )
417
                & (eight_bit_data_or_control_in[7:5] == 3'h7);
418 18 bbeaver
 
419
// The low bit of the MSB is a pass-through, except when the alternate
420
//   encoding of the value is used to prevent unintentional long runs.
421
  assign  first_level_encoded_data[6] = eight_bit_data_or_control_in[5]
422
                                      & ~use_alternate_encoding;
423
 
424
// The second bit of the MSB is a pass-through except when the input
425
//   is all 0's.
426
  assign  first_level_encoded_data[7] = eight_bit_data_or_control_in[6]
427 22 bbeaver
                                      | (eight_bit_data_or_control_in[7:5]  == 3'h0);
428 18 bbeaver
 
429
// The top bit of the encoded MSB data is the same as the input MSB data.
430
  assign  first_level_encoded_data[8] = eight_bit_data_or_control_in[7];
431
 
432
// Bit "j" is chosen to guarantee that there are enough transitions,
433
//   and to control the disparity caused by each pattern.
434
  assign  first_level_encoded_data[9] =
435
                  (eight_bit_data_or_control_in[7:5] == 3'h1)
436
                | (eight_bit_data_or_control_in[7:5] == 3'h2)
437
                | use_alternate_encoding;
438
 
439
// Now calculate the other information needed to produce the MSB output data
440
  wire    invert_MSB_if_LSB_disparity_is_positive =
441
                  (eight_bit_data_or_control_in[7:5] == 3'h3)
442
                | (eight_bit_data_or_control_in[7:5] == 3'h7);
443
 
444
  wire    invert_MSB_if_LSB_disparity_is_negative =
445
                  (eight_bit_data_or_control_in[7:5] == 3'h0)
446
                | (eight_bit_data_or_control_in[7:5] == 3'h4)
447
                | (   input_is_control
448
                    & (   (eight_bit_data_or_control_in[7:5] == 3'h1)
449
                        | (eight_bit_data_or_control_in[7:5] == 3'h2)
450
                        | (eight_bit_data_or_control_in[7:5] == 3'h5)
451 22 bbeaver
                        | (eight_bit_data_or_control_in[7:5] == 3'h6)
452
                       )
453
                  );
454 18 bbeaver
 
455
  wire    MSB_toggle_running_disparity =
456
                  (eight_bit_data_or_control_in[7:5] == 3'h0)
457
                | (eight_bit_data_or_control_in[7:5] == 3'h4)
458
                | (eight_bit_data_or_control_in[7:5] == 3'h7);
459
 
460
// Keep track of the running disparity.  If 1'b1, the disparity is positive.
461
  always @(posedge clk)
462
  begin
463
    if (reset == 1'b1)
464
    begin
465
      Running_Disparity <= 1'b0;  // start negative
466
    end
467
    else
468
    begin
469
      Running_Disparity <= Running_Disparity
470
                         ^ LSB_toggle_running_disparity
471
                         ^ MSB_toggle_running_disparity;
472
    end
473
  end
474
 
475
// Decide whether to invert the encoded data;
476
  wire    Invert_LSB = (   (Running_Disparity == 1'b1)
477
                         & (invert_LSB_if_input_disparity_is_positive == 1'b1) )
478
                     | (   (Running_Disparity == 1'b0)
479
                         & (invert_LSB_if_input_disparity_is_negative == 1'b1) );
480
 
481
  wire    Invert_MSB = (   ((Running_Disparity ^ LSB_toggle_running_disparity) == 1'b1)
482
                         & (invert_MSB_if_LSB_disparity_is_positive == 1'b1) )
483
                     | (   ((Running_Disparity ^ LSB_toggle_running_disparity) == 1'b0)
484
                         & (invert_MSB_if_LSB_disparity_is_negative == 1'b1) );
485
 
486
// Calculate the actual encoded data.
487
  reg    [9:0] ten_bit_encoded_data_out;
488
  reg     invalid_control;
489
 
490 22 bbeaver
  always @(posedge clk)
491 18 bbeaver
  begin
492
    if (reset == 1'b1)
493
    begin
494
      ten_bit_encoded_data_out[9:0] <= 10'h000;
495
      invalid_control <= 1'b0;
496
    end
497
    else
498
    begin
499
      ten_bit_encoded_data_out[5:0] <=
500
                  {6{Invert_LSB}} ^ first_level_encoded_data[5:0];
501
      ten_bit_encoded_data_out[9:6] <=
502
                  {4{Invert_MSB}} ^ first_level_encoded_data[9:6];
503
      invalid_control <= input_is_control
504
                & ~(   LSB_is_28  // all MSB bits are valid
505 22 bbeaver
                     | (   LSB_is_23_27_29_30
506 18 bbeaver
                         & (eight_bit_data_or_control_in[7:5] == 3'h7)  // MSB must be 7
507 22 bbeaver
                        )
508
                   );
509 18 bbeaver
    end
510
  end
511
endmodule
512
 
513
// Convert 10-bit code to 8-bit binary or 8-bit control code
514
 
515
module decode_10b_8b (
516
  ten_bit_encoded_data_in,
517
  eight_bit_data_or_control_out,
518
  output_is_control,
519 22 bbeaver
  invalid_encoded_data,
520 18 bbeaver
  clk,
521
  reset
522
);
523
  input  [9:0] ten_bit_encoded_data_in;
524
  output [7:0] eight_bit_data_or_control_out;
525
  output  output_is_control;
526 22 bbeaver
  output  invalid_encoded_data;
527 18 bbeaver
  input   clk, reset;
528
 
529
// Data is encoded as described in the encode_8b_10b module above.
530
// This module tries to extract valid data or control info from the
531
//   encoded input data.
532
//
533
// This module depends on the data being correctly 10-bit aligned.
534
//  the LSB of the input must be the "a" bit as described above.
535
//
536
// This module tries to detect errors in the code sequence as it arrives.
537
// Errors are when an illegal bit sequence arrives, or when the disparity
538
//   of the input data goes beyond 1 bit.  This would happen if the sender
539
//   did not correctly use alternate encodings of output data.
540
 
541 19 bbeaver
// Accumulate the new data.  Calculate ignoring the running disparity;
542
  wire   [7:0] decoded_data;
543
 
544 22 bbeaver
// Calculate the values for the 6 -> 5 decoding
545 19 bbeaver
 
546
// Discover important details about the incoming numbers.
547 18 bbeaver
  wire   [1:0] LSB_02_Population = ten_bit_encoded_data_in[0]  // full adder
548
                                 + ten_bit_encoded_data_in[1]
549
                                 + ten_bit_encoded_data_in[2];
550
  wire   [1:0] LSB_35_Population = ten_bit_encoded_data_in[3]  // full adder
551
                                 + ten_bit_encoded_data_in[4]
552
                                 + ten_bit_encoded_data_in[5];
553 22 bbeaver
  wire   [2:0] LSB_bottom_4_Population = {1'b0, LSB_02_Population[1:0]}
554
                                       + {2'b00, ten_bit_encoded_data_in[3]};
555 18 bbeaver
  wire   [2:0] LSB_Population = {1'b0, LSB_02_Population[1:0]}  // allowed: 2, 3, 4
556 19 bbeaver
                              + {1'b0, LSB_35_Population[1:0]};  // illegal: 0, 1, 5, 6
557 18 bbeaver
 
558 19 bbeaver
// As can be seen, in many of the LSB encodings the bottom
559
//   4 of the decoded data are identical to the input
560
//   data.  (These are noted with a trailing "!")
561
//
562
// The bottom 4 bits can be used directly in these cases (which are all cases
563
//   where the number of bits in the input are equil to 3 except for 7):
564
//   3 5 6 9 10 11 12 13 14 17 18 19 20 21 22 25 26 28
565 18 bbeaver
 
566 19 bbeaver
// The bottom 4 bits must be inverted before use in these cases:  (MSB right)
567
//   011101 101101 110101 111001 000101 001001 010001 100001 000111 110000
568 22 bbeaver
  wire    LSB_Invert_Before_Use = (   (ten_bit_encoded_data_in[5:4] == 2'b10)
569
                                    & (   (LSB_bottom_4_Population[2:0] == 3'h1)
570
                                        | (LSB_bottom_4_Population[2:0] == 3'h3) )
571
                                  )
572
                                | (ten_bit_encoded_data_in[5:0] == 6'b111000)  // LSB to right
573
                                | (ten_bit_encoded_data_in[5:0] == 6'b000011);
574 19 bbeaver
 
575
// Values must be substituted in these cases:
576
  wire    LSB_is_0_16_a  = (ten_bit_encoded_data_in[5:0] == 6'b000110)  // LSB to right
577
                         | (ten_bit_encoded_data_in[5:0] == 6'b110110);
578
 
579
  wire    LSB_is_0_16_b  = (ten_bit_encoded_data_in[5:0] == 6'b111001)  // LSB to right
580
                         | (ten_bit_encoded_data_in[5:0] == 6'b001001);
581
 
582
  wire    LSB_is_15_31_a = (ten_bit_encoded_data_in[5:0] == 6'b000101)  // LSB to right
583
                         | (ten_bit_encoded_data_in[5:0] == 6'b110101);
584
 
585
  wire    LSB_is_15_31_b = (ten_bit_encoded_data_in[5:0] == 6'b111010)  // LSB to right
586
                         | (ten_bit_encoded_data_in[5:0] == 6'b001010);
587
 
588
  wire    LSB_is_24_a    = (ten_bit_encoded_data_in[5:0] == 6'b001100);  // LSB to right
589
  wire    LSB_is_24_b    = (ten_bit_encoded_data_in[5:0] == 6'b110011);  // LSB to right
590
 
591 22 bbeaver
// Notice when these codes occur.  They are the only time Alternate D.x.7 data
592
//   can be used.  This is looked for below to detect errors.
593
  wire    LSB_is_11_13_14 = (ten_bit_encoded_data_in[5:0] == 6'b001011)  // LSB to right
594
                          | (ten_bit_encoded_data_in[5:0] == 6'b001101)
595
                          | (ten_bit_encoded_data_in[5:0] == 6'b001110);
596
 
597
  wire    LSB_is_17_18_20 = (ten_bit_encoded_data_in[5:0] == 6'b110001)  // LSB to right
598
                          | (ten_bit_encoded_data_in[5:0] == 6'b110010)
599
                          | (ten_bit_encoded_data_in[5:0] == 6'b110100);
600
 
601 19 bbeaver
// Control signals must be called out when recognized.
602
  wire    LSB_is_23_27_29_30 = (   (ten_bit_encoded_data_in[5:4] == 2'b01)
603
                                 & (LSB_bottom_4_Population[2:0] == 3'h3) )
604
                             | (   (ten_bit_encoded_data_in[5:4] == 2'b10)
605
                                 & (LSB_bottom_4_Population[2:0] == 3'h1) );
606
 
607
  wire    LSB_is_K28  = (ten_bit_encoded_data_in[5:0] == 6'b111100)  // LSB to right
608
                      | (ten_bit_encoded_data_in[5:0] == 6'b000011);
609
 
610
// calculate the bottom 4 bits of decoded data
611 22 bbeaver
  wire   [3:0] LSB_XOR_Term = {4{LSB_Invert_Before_Use}}  // invert all signals with alternate values
612 19 bbeaver
                            | {1'b0,  LSB_is_0_16_a, LSB_is_0_16_a,  1'b0}  // make 0, 16 into 0
613
                            | {LSB_is_0_16_b,  1'b0, 1'b0,  LSB_is_0_16_b}  // make 0, 16 into 0
614
                            | {LSB_is_15_31_a, 1'b0, LSB_is_15_31_a, 1'b0}  // make 15, 31 into 15
615
                            | {1'b0, LSB_is_15_31_b, 1'b0, LSB_is_15_31_b}  // make 15, 31 into 15
616
                            | {1'b0, LSB_is_24_a,    1'b0,           1'b0}  // make 24 into 24
617
                            | {LSB_is_24_b, 1'b0, LSB_is_24_b, LSB_is_24_b};  // make 24 into 24
618
 
619
  assign  decoded_data[3:0] = ten_bit_encoded_data_in[3:0] ^ LSB_XOR_Term[3:0];
620
 
621
// The next bit is harder.  I don't know if this is minimal
622
  assign  decoded_data[4] = (ten_bit_encoded_data_in[5:0] == 6'b001001)  // LSB to right
623
                          | (ten_bit_encoded_data_in[5:0] == 6'b001010)
624
                          | (ten_bit_encoded_data_in[5:0] == 6'b001100)
625
                          | (ten_bit_encoded_data_in[5:3] == 3'b110)
626
                          | (   (ten_bit_encoded_data_in[5:4] == 2'b01)
627
                              & (LSB_bottom_4_Population[2:0] == 3'h2) )
628
                          | LSB_is_23_27_29_30
629
                          | LSB_is_K28;
630
 
631 22 bbeaver
// Calculate the values for the 4 -> 3 decoding
632 19 bbeaver
 
633 22 bbeaver
// The bottom 2 bits of the MSB must always be inverted before use in these
634
//    cases:  (MSB right)  0011, 1101, 0001
635
// When the LSB indicate that the byte contains a K28, and the bottom 6 bits
636
//   have a negative disparity, invert these before using: (MSB right)
637
//   0110, 1010, 0101, 1001
638
// Only 2 of these are needed to greate singular commas.  I don't understand
639
//   why they made the other special cases.  Very odd
640 19 bbeaver
 
641 22 bbeaver
  wire    MSB_Invert_Before_Use = (ten_bit_encoded_data_in[9:6] == 4'b1100)  // LSB to right
642
                                | (ten_bit_encoded_data_in[9:6] == 4'b1011)
643
                                | (ten_bit_encoded_data_in[9:6] == 4'b1000)
644
                                | (   (ten_bit_encoded_data_in[5:0] == 6'b000011)
645
                                    & (   (ten_bit_encoded_data_in[9:6] == 4'b0110)
646
                                        | (ten_bit_encoded_data_in[9:6] == 4'b0101)
647
                                        | (ten_bit_encoded_data_in[9:6] == 4'b1010)
648
                                        | (ten_bit_encoded_data_in[9:6] == 4'b1001)
649
                                      )
650
                                  );
651 19 bbeaver
 
652 22 bbeaver
// Values must be substituted in these cases:
653
  wire    MSB_0_value_a = (ten_bit_encoded_data_in[9:6] == 4'b0010);  // LSB to right
654
  wire    MSB_0_value_b = (ten_bit_encoded_data_in[9:6] == 4'b1101);
655 19 bbeaver
 
656 22 bbeaver
  wire    alternate_MSB_a = (ten_bit_encoded_data_in[9:6] == 4'b1110);  // LSB to right
657
  wire    alternate_MSB_b = (ten_bit_encoded_data_in[9:6] == 4'b0001);
658 19 bbeaver
 
659 22 bbeaver
  wire    primary_MSB_a = (ten_bit_encoded_data_in[9:6] == 4'b0111);  // LSB to right
660
  wire    primary_MSB_b = (ten_bit_encoded_data_in[9:6] == 4'b1000);
661 18 bbeaver
 
662 22 bbeaver
  wire   [2:0] MSB_XOR_Term = {3{MSB_Invert_Before_Use}}
663
                            | {1'b0, MSB_0_value_a, 1'b0}
664
                            | {MSB_0_value_b, 1'b0, MSB_0_value_b}
665
                            | {1'b0, 1'b0, alternate_MSB_a}
666
                            | {alternate_MSB_b, alternate_MSB_b, 1'b0};
667 18 bbeaver
 
668 22 bbeaver
  assign  decoded_data[7:5] = ten_bit_encoded_data_in[8:6] ^ MSB_XOR_Term[2:0];
669
 
670
  wire    decoded_control = (   LSB_is_23_27_29_30
671
                              & (alternate_MSB_a | alternate_MSB_b))
672
                          | LSB_is_K28;
673
 
674 18 bbeaver
// Keep track of the running disparity.  If 1'b1, the disparity is positive.
675 22 bbeaver
 
676
  wire   [1:0] MSB_01_Population = ten_bit_encoded_data_in[6]  // half adder
677
                                 + ten_bit_encoded_data_in[7];
678
  wire   [1:0] MSB_23_Population = ten_bit_encoded_data_in[8]  // half adder
679
                                 + ten_bit_encoded_data_in[9];
680
  wire   [2:0] MSB_Population = {1'b0, MSB_01_Population[1:0]}  // 1, 2, 3
681
                              + {1'b0, MSB_23_Population[1:0]};
682
 
683
  wire   [3:0] Code_Population = {1'b0, LSB_Population[2:0]}  // 4, 5, 6
684
                               + {1'b0, MSB_Population[2:0]};
685
 
686 18 bbeaver
  reg     Running_Disparity;
687
 
688
  always @(posedge clk)
689
  begin
690
    if (reset == 1'b1)
691
    begin
692
      Running_Disparity <= 1'b0;  // start negative
693
    end
694
    else
695
    begin
696 22 bbeaver
      Running_Disparity <= (Code_Population[3:0] == 4'h6)
697
                         ? 1'b1
698
                         : (   (Code_Population[3:0] == 4'h4)
699
                             ? 1'b0
700
                             : Running_Disparity);
701 18 bbeaver
    end
702
  end
703
 
704 22 bbeaver
// Detect invalid code values.
705
 
706
  wire    too_many_bits_in_first_nibble =
707
                (LSB_bottom_4_Population[2:0] > 3'h3);
708
  wire    too_few_bits_in_first_nibble =
709
                (LSB_bottom_4_Population[2:0] < 3'h1);
710
 
711
  wire    too_many_bits_in_LSB = (LSB_Population[2:0] > 3'h4);
712
  wire    too_few_bits_in_LSB = (LSB_Population[2:0] < 3'h2);
713
 
714
  wire    too_many_bits_in_MSB = (MSB_Population[2:0] > 3'h3);
715
  wire    too_few_bits_in_MSB = (LSB_Population[2:0] < 3'h1);
716
 
717
  wire    too_many_bits_in_entire_code = (Code_Population[3:0] > 4'h6);
718
  wire    too_few_bits_in_entire_code = (Code_Population[3:0] < 4'h4);
719
 
720
  wire    LSB_inconsistent_with_running_disparity =
721
                  (   (Running_Disparity == 1'b1)
722
                    & (   (LSB_Population[2:0] == 3'h4)
723
                        | (ten_bit_encoded_data_in[5:0] == 6'b000111)  // X.7 negative disparity
724
                      ) )
725
                | (   (Running_Disparity == 1'b0)
726
                    & (   (LSB_Population[2:0] == 3'h2)
727
                        | (ten_bit_encoded_data_in[5:0] == 6'b111000)  // X.7 positive disparity
728
                      ) );
729
 
730
  wire    LSB_code_7_positive_but_MSB_inconsistent =
731
                  (ten_bit_encoded_data_in[5:0] == 6'b111000)  // X.7 positive disparity
732
                & (   (MSB_Population[2:0] == 3'h3)  // too many bits in MSB
733
                    | (ten_bit_encoded_data_in[9:6] == 4'b0011)  // Y.3 negative disparity
734
                  );
735
 
736
  wire    LSB_code_7_negative_but_MSB_inconsistent =
737
                  (ten_bit_encoded_data_in[5:0] == 6'b000111)  // X.7 negative disparity
738
                & (   (MSB_Population[2:0] == 3'h1)  // too few bits in MSB
739
                    | (ten_bit_encoded_data_in[9:6] == 4'b1100)  // Y.3 positive disparity
740
                  );
741
 
742
  wire    MSB_code_3_positive_but_LSB_inconsistent =
743
                  (ten_bit_encoded_data_in[9:6] == 4'b1100)  // X.7 positive disparity
744
                & (LSB_Population[2:0] == 3'h2);  // too few bits in LSB
745
 
746
  wire    MSB_code_3_negative_but_LSB_inconsistent =
747
                  (ten_bit_encoded_data_in[9:6] == 4'b0011)  // X.7 negative disparity
748
                & (LSB_Population[2:0] == 3'h4);  // too many bits in LSB
749
 
750
  wire    alternate_encoding_not_used_when_required =
751
                  ((Running_Disparity == 1'b1) & (LSB_is_11_13_14) & primary_MSB_b)
752
                | ((Running_Disparity == 1'b0) & (LSB_is_17_18_20) & primary_MSB_a)
753
                | (LSB_is_K28 & (primary_MSB_a | primary_MSB_b));
754
 
755
  wire    primary_encoding_not_used_when_required =
756
                  ((Running_Disparity == 1'b0) & (LSB_is_11_13_14) & alternate_MSB_b)
757
                | ((Running_Disparity == 1'b1) & (LSB_is_17_18_20) & alternate_MSB_a);
758
 
759
  wire    detected_invalid_8b_10b_sequence = too_many_bits_in_first_nibble
760
                                           | too_few_bits_in_first_nibble
761
                                           | too_many_bits_in_LSB
762
                                           | too_few_bits_in_LSB
763
                                           | too_many_bits_in_MSB
764
                                           | too_few_bits_in_MSB
765
                                           | too_many_bits_in_entire_code
766
                                           | too_few_bits_in_entire_code
767
                                           | LSB_inconsistent_with_running_disparity
768
                                           | LSB_code_7_positive_but_MSB_inconsistent
769
                                           | LSB_code_7_negative_but_MSB_inconsistent
770
                                           | MSB_code_3_positive_but_LSB_inconsistent
771
                                           | MSB_code_3_negative_but_LSB_inconsistent
772
                                           | alternate_encoding_not_used_when_required
773
                                           | primary_encoding_not_used_when_required;
774
 
775 18 bbeaver
// Calculate the actual decoded data.
776
  reg    [7:0] eight_bit_data_or_control_out;
777
  reg     output_is_control;
778
  reg     invalid_encoded_data;
779
 
780 22 bbeaver
  always @(posedge clk)
781 18 bbeaver
  begin
782
    if (reset == 1'b1)
783
    begin
784
      eight_bit_data_or_control_out[7:0] <= 8'h00;
785
      output_is_control <= 1'b0;
786
      invalid_encoded_data <= 1'b0;
787
    end
788
    else
789
    begin
790 19 bbeaver
      eight_bit_data_or_control_out[7:0] <= decoded_data[7:0];
791 22 bbeaver
      output_is_control <= decoded_control;
792
      invalid_encoded_data <= detected_invalid_8b_10b_sequence
793
                            & (ten_bit_encoded_data_in[9:0] != 10'b0000_000000)  // NOTE TEMPORARY
794
                            ;
795 18 bbeaver
    end
796
  end
797
endmodule
798
 
799 24 bbeaver
// `define TEST_8B_10B
800 18 bbeaver
`ifdef TEST_8B_10B
801 24 bbeaver
// This simulates in between 6 and 7 minutes on a 400 MHz Ultra using verilog XL.
802
// This does not complete before filling up the disk on a 300 MHz K6 using Verilogger PRO.
803 18 bbeaver
module test_8b_10b;
804
  reg    [8:0] test_data;
805 23 bbeaver
  reg    [8:0] test_data_second;
806
  reg    [8:0] limit;
807 24 bbeaver
  reg    [7:0] control_byte;
808
  reg    [7:0] control_byte_second;
809 18 bbeaver
  reg     test_control;
810
 
811 19 bbeaver
  reg    [7:0] eight_bit_data_or_control_in;
812 18 bbeaver
  reg     input_is_control;
813 22 bbeaver
  reg     mess_up_link_disparity;
814 19 bbeaver
  wire   [9:0] ten_bit_encoded_data_out;
815
  wire    invalid_control;
816 18 bbeaver
 
817 19 bbeaver
  wire   [7:0] eight_bit_data_or_control_out;
818
  wire    output_is_control;
819 22 bbeaver
  wire    invalid_encoded_data;
820 18 bbeaver
 
821 19 bbeaver
  reg     clk, reset;
822 18 bbeaver
 
823 23 bbeaver
  reg     found_singular_comma;
824
 
825 22 bbeaver
task set_to_negative_disparity;
826 18 bbeaver
  begin
827 22 bbeaver
    clk = 1'b0;  reset = 1'b1; #1;
828
    clk = 1'b1;  reset = 1'b1; #1;  // do reset, setting sender to negative disparity
829
    clk = 1'b0;  reset = 1'b1; #1;
830
    clk = 1'b0;  reset = 1'b0; #1;
831
  end
832
endtask
833 19 bbeaver
 
834 22 bbeaver
task set_to_positive_disparity;
835
  begin
836
    clk = 1'b0;  reset = 1'b1; #1;
837
    clk = 1'b1;  reset = 1'b1; #1;  // do reset, setting sender to negative disparity
838
    clk = 1'b0;  reset = 1'b1; #1;
839
    clk = 1'b0;  reset = 1'b0; #1;
840
 
841
    eight_bit_data_or_control_in[7:0] = 8'b111_00011; #1;
842
    clk = 1'b1; #1;  // switch to a positive running disparity
843
    clk = 1'b0; #1;
844
  end
845
endtask
846
 
847
task check;
848
  input disparity;
849
  input  [7:0] test_data;
850 23 bbeaver
  input   do_control;
851 22 bbeaver
  reg    [9:0] latched_code;
852
  begin
853
    if (disparity == 1'b1)
854
      set_to_positive_disparity;
855
    else
856
      set_to_negative_disparity;
857
 
858 23 bbeaver
    input_is_control = do_control;
859 22 bbeaver
    eight_bit_data_or_control_in[7:0] = test_data[7:0]; #1;  // inputs settle
860
    clk = 1'b1; #1;  // encoded data available
861
    clk = 1'b0; #1;
862
 
863
    latched_code[9:0] = ten_bit_encoded_data_out[9:0];
864
 
865 18 bbeaver
    input_is_control = 1'b0;
866 22 bbeaver
    eight_bit_data_or_control_in[7:0] = 8'b010_00011; #1;
867
    clk = 1'b1; #1;  // decoded data available
868
    clk = 1'b0; #1;
869
 
870
    if (   (eight_bit_data_or_control_out[7:0] !== test_data[7:0])
871 23 bbeaver
         | (output_is_control !== do_control)
872 22 bbeaver
         | (invalid_encoded_data !== 1'b0)
873
       )
874 18 bbeaver
    begin
875 22 bbeaver
      $display ("!!! test data, result %d %d %b_%b %x %d %b %b",
876
                 test_data[7:5], test_data[4:0],
877
                 latched_code[9:6], latched_code[5:0],
878 19 bbeaver
                 eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
879 22 bbeaver
                 output_is_control, invalid_encoded_data);
880 18 bbeaver
    end
881 22 bbeaver
  end
882
endtask
883
 
884 23 bbeaver
function look_for_singular_comma;
885
  input  [6:0] data;
886
  begin
887
    if (   (data[0] == data[1])
888
         & (data[0] == ~data[2])
889
         & (data[0] == ~data[3])
890
         & (data[0] == ~data[4])
891
         & (data[0] == ~data[5])
892
         & (data[0] == ~data[6])
893
       )
894
    begin
895
      look_for_singular_comma = 1'b1;
896
    end
897
    else
898
    begin
899
      look_for_singular_comma = 1'b0;
900
    end
901
  end
902
endfunction
903
 
904 24 bbeaver
task check_pair;  // Data then Data or Control then Data
905 23 bbeaver
  input disparity;
906
  input  [7:0] test_data;
907
  input  [7:0] test_data_second;
908
  input   do_control;
909
  input   want_singular_comma;
910
  reg    [9:0] latched_code;
911 24 bbeaver
  reg    [19:0] two_bytes_of_codes_back_to_back;
912
 
913 23 bbeaver
  begin
914
    if (disparity == 1'b1)
915
      set_to_positive_disparity;
916
    else
917
      set_to_negative_disparity;
918
 
919
    input_is_control = do_control;
920
    eight_bit_data_or_control_in[7:0] = test_data[7:0]; #1;  // inputs settle
921
    clk = 1'b1; #1;  // encoded data available
922
    clk = 1'b0; #1;
923
 
924
    latched_code[9:0] = ten_bit_encoded_data_out[9:0];
925
    two_bytes_of_codes_back_to_back[9:0] = ten_bit_encoded_data_out[9:0];
926
 
927
    input_is_control = 1'b0;
928
    eight_bit_data_or_control_in[7:0] = test_data_second[7:0]; #1;  // inputs settle
929
    clk = 1'b1; #1;  // decoded data available
930
    clk = 1'b0; #1;
931
 
932
    if (   (eight_bit_data_or_control_out[7:0] !== test_data[7:0])
933
         | (output_is_control !== do_control)
934
         | (invalid_encoded_data !== 1'b0)
935
       )
936
    begin
937
      $display ("!!! test data, result %d %d %b_%b %x %d %b %b",
938
                 test_data[7:5], test_data[4:0],
939
                 latched_code[9:6], latched_code[5:0],
940
                 eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
941
                 output_is_control, invalid_encoded_data);
942
    end
943
 
944
    latched_code[9:0] = ten_bit_encoded_data_out[9:0];
945
    two_bytes_of_codes_back_to_back[19:10] = ten_bit_encoded_data_out[9:0];
946
 
947
    input_is_control = 1'b0;
948
    eight_bit_data_or_control_in[7:0] = 8'b010_00011; #1;
949
    clk = 1'b1; #1;  // decoded data available
950
    clk = 1'b0; #1;
951
 
952
    if (   (eight_bit_data_or_control_out[7:0] !== test_data_second[7:0])
953
         | (output_is_control !== 1'b0)
954
         | (invalid_encoded_data !== 1'b0)
955
       )
956
    begin
957
      $display ("!!! test data second, result %d %d %b_%b %x %d %b %b",
958
                 test_data_second[7:5], test_data_second[4:0],
959
                 latched_code[9:6], latched_code[5:0],
960
                 eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
961
                 output_is_control, invalid_encoded_data);
962
    end
963
 
964
    if (~want_singular_comma)
965
    begin
966
      if (   look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0])
967
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
968
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
969
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
970
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
971
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
972
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
973
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
974
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
975 24 bbeaver
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9])
976
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10])
977
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
978
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
979
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
980 23 bbeaver
      begin
981
        $display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
982
                   test_data[7:0], test_data_second[7:0],
983
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
984
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
985
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
986
                   output_is_control, invalid_encoded_data);
987
      end
988
    end
989
    else  // want a singular comma
990
    begin
991 24 bbeaver
      if (!look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0]))
992
      begin
993
        $display ("!!! missing singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
994
                   test_data[7:0], test_data_second[7:0],
995
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
996
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
997
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
998
                   output_is_control, invalid_encoded_data);
999
      end
1000
      if (   look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
1001
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
1002
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
1003
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
1004
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
1005
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
1006
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
1007
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
1008
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9])
1009
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10])
1010
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
1011
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
1012
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
1013
      begin
1014
        $display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
1015
                   test_data[7:0], test_data_second[7:0],
1016
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
1017
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
1018
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1019
                   output_is_control, invalid_encoded_data);
1020
      end
1021
    end
1022
  end
1023
endtask
1024
 
1025
task check_pair_2;  // Data followed by Control or Control followed by Control
1026
  input disparity;
1027
  input  [7:0] test_data;
1028
  input  [7:0] test_data_second;
1029
  input   first_control;
1030
  input   want_first_singular_comma;
1031
  input   second_control;
1032
  input   want_second_singular_comma;
1033
  reg    [9:0] latched_code;
1034
  reg    [19:0] two_bytes_of_codes_back_to_back;
1035
 
1036
  begin
1037
    if (disparity == 1'b1)
1038
      set_to_positive_disparity;
1039
    else
1040
      set_to_negative_disparity;
1041
 
1042
    input_is_control = first_control;
1043
    eight_bit_data_or_control_in[7:0] = test_data[7:0]; #1;  // inputs settle
1044
    clk = 1'b1; #1;  // encoded data available
1045
    clk = 1'b0; #1;
1046
 
1047
    latched_code[9:0] = ten_bit_encoded_data_out[9:0];
1048
    two_bytes_of_codes_back_to_back[9:0] = ten_bit_encoded_data_out[9:0];
1049
 
1050
    input_is_control = second_control;
1051
    eight_bit_data_or_control_in[7:0] = test_data_second[7:0]; #1;  // inputs settle
1052
    clk = 1'b1; #1;  // decoded data available
1053
    clk = 1'b0; #1;
1054
 
1055
    if (   (eight_bit_data_or_control_out[7:0] !== test_data[7:0])
1056
         | (output_is_control !== first_control)
1057
         | (invalid_encoded_data !== 1'b0)
1058
       )
1059
    begin
1060
      $display ("!!! test data, result %d %d %b_%b %x %d %b %b",
1061
                 test_data[7:5], test_data[4:0],
1062
                 latched_code[9:6], latched_code[5:0],
1063
                 eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1064
                 output_is_control, invalid_encoded_data);
1065
    end
1066
 
1067
    latched_code[9:0] = ten_bit_encoded_data_out[9:0];
1068
    two_bytes_of_codes_back_to_back[19:10] = ten_bit_encoded_data_out[9:0];
1069
 
1070
    input_is_control = 1'b0;
1071
    eight_bit_data_or_control_in[7:0] = 8'b010_00011; #1;
1072
    clk = 1'b1; #1;  // decoded data available
1073
    clk = 1'b0; #1;
1074
 
1075
    if (   (eight_bit_data_or_control_out[7:0] !== test_data_second[7:0])
1076
         | (output_is_control !== second_control)
1077
         | (invalid_encoded_data !== 1'b0)
1078
       )
1079
    begin
1080
      $display ("!!! test data second, result %d %d %b_%b %x %d %b %b",
1081
                 test_data_second[7:5], test_data_second[4:0],
1082
                 latched_code[9:6], latched_code[5:0],
1083
                 eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1084
                 output_is_control, invalid_encoded_data);
1085
    end
1086
 
1087
    if (~want_first_singular_comma)
1088
    begin
1089
      if (   look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0])
1090 23 bbeaver
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
1091
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
1092
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
1093
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
1094
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
1095
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
1096
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
1097
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
1098
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9]) )
1099
      begin
1100 24 bbeaver
        $display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
1101
                   test_data[7:0], test_data_second[7:0],
1102
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
1103
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
1104
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1105
                   output_is_control, invalid_encoded_data);
1106
      end
1107
    end
1108
    else  // want a singular comma in the first byte
1109
    begin
1110
      if (!look_for_singular_comma (two_bytes_of_codes_back_to_back[6:0]))
1111
      begin
1112 23 bbeaver
        $display ("!!! missing singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
1113
                   test_data[7:0], test_data_second[7:0],
1114
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
1115
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
1116
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1117
                   output_is_control, invalid_encoded_data);
1118
      end
1119 24 bbeaver
      if (   look_for_singular_comma (two_bytes_of_codes_back_to_back[7:1])
1120
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[8:2])
1121
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[9:3])
1122
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[10:4])
1123
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[11:5])
1124
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[12:6])
1125
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[13:7])
1126
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[14:8])
1127
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[15:9]) )
1128
      begin
1129
        $display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
1130
                   test_data[7:0], test_data_second[7:0],
1131
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
1132
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
1133
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1134
                   output_is_control, invalid_encoded_data);
1135
      end
1136 23 bbeaver
    end
1137 24 bbeaver
    if (~want_second_singular_comma)
1138
    begin
1139
      if (   look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10])
1140
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
1141
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
1142
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
1143
      begin
1144
        $display ("!!! unexpected singular comma, result %d %d %b_%b %b_%b %b %b %b %b",
1145
                   test_data[7:0], test_data_second[7:0],
1146
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
1147
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
1148
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1149
                   output_is_control, invalid_encoded_data);
1150
      end
1151
    end
1152
    else  // want a singular comma in the second byte
1153
    begin
1154
      if (!look_for_singular_comma (two_bytes_of_codes_back_to_back[16:10]))
1155
      begin
1156
        $display ("!!! missing singular comma 2, result %d %d %b_%b %b_%b %b %b %b %b",
1157
                   test_data[7:0], test_data_second[7:0],
1158
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
1159
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
1160
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1161
                   output_is_control, invalid_encoded_data);
1162
      end
1163
      if (   look_for_singular_comma (two_bytes_of_codes_back_to_back[17:11])
1164
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[18:12])
1165
           | look_for_singular_comma (two_bytes_of_codes_back_to_back[19:13]) )
1166
      begin
1167
        $display ("!!! unexpected singular comma 2, result %d %d %b_%b %b_%b %b %b %b %b",
1168
                   test_data[7:0], test_data_second[7:0],
1169
                   two_bytes_of_codes_back_to_back[9:6], two_bytes_of_codes_back_to_back[5:0],
1170
                   two_bytes_of_codes_back_to_back[19:16], two_bytes_of_codes_back_to_back[15:10],
1171
                   eight_bit_data_or_control_out[7:5], eight_bit_data_or_control_out[4:0],
1172
                   output_is_control, invalid_encoded_data);
1173
      end
1174
    end
1175 23 bbeaver
  end
1176
endtask
1177
 
1178 24 bbeaver
function [7:0] pick_control_byte;
1179
  input  [3:0] index;
1180
  begin
1181
    case (index[3:0])
1182
      0:       pick_control_byte[7:0] = `K_23_7;
1183
      1:       pick_control_byte[7:0] = `K_27_7;
1184
      2:       pick_control_byte[7:0] = `K_28_0;
1185
      3:       pick_control_byte[7:0] = `K_28_1;
1186
      4:       pick_control_byte[7:0] = `K_28_2;
1187
      5:       pick_control_byte[7:0] = `K_28_3;
1188
      6:       pick_control_byte[7:0] = `K_28_4;
1189
      7:       pick_control_byte[7:0] = `K_28_5;
1190
      8:       pick_control_byte[7:0] = `K_28_6;
1191
      9:       pick_control_byte[7:0] = `K_28_7;
1192
      10:      pick_control_byte[7:0] = `K_29_7;
1193
      default: pick_control_byte[7:0] = `K_30_7;
1194
    endcase
1195
  end
1196
endfunction
1197
 
1198 22 bbeaver
  initial
1199
  begin
1200
    mess_up_link_disparity = 1'b0;
1201
 
1202
    $display ("test 32 LSB data values starting with negative disparity");
1203
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h020;
1204
                      test_data[8:0] = test_data[8:0] + 9'h001)
1205 18 bbeaver
    begin
1206 22 bbeaver
      check (0, test_data[7:0], 1'b0);
1207 18 bbeaver
    end
1208
 
1209 22 bbeaver
    $display ("test 8 MSB data values starting with negative disparity");
1210
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1211
                      test_data[8:0] = test_data[8:0] + 9'h001)
1212 18 bbeaver
    begin
1213 22 bbeaver
      check (0, (test_data[2:0] << 5) | 5'h03, 1'b0);
1214 18 bbeaver
    end
1215 22 bbeaver
 
1216
    $display ("test 8 MSB data values starting with negative disparity");
1217
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1218
                      test_data[8:0] = test_data[8:0] + 9'h001)
1219 18 bbeaver
    begin
1220 22 bbeaver
      check (0, (test_data[2:0] << 5) | 5'h0B, 1'b0);  // 11
1221 18 bbeaver
    end
1222 22 bbeaver
 
1223
    $display ("test 8 MSB data values starting with negative disparity");
1224
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1225
                      test_data[8:0] = test_data[8:0] + 9'h001)
1226
    begin
1227
      check (0, (test_data[2:0] << 5) | 5'h11, 1'b0);  // 17
1228
    end
1229
 
1230
    $display ("test control starting with negative disparity");
1231
    check (0, `K_23_7, 1'b1);
1232
    check (0, `K_27_7, 1'b1);
1233
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1234
                      test_data[8:0] = test_data[8:0] + 9'h001)
1235
    begin
1236
      check (0, `K_28_0 | (test_data[2:0] << 5), 1'b1);
1237
    end
1238
    check (0, `K_29_7, 1'b1);
1239
    check (0, `K_30_7, 1'b1);
1240
 
1241
//    $display ("invalid control character with negative disparity");
1242
//    check (0, 8'h0, 1'b1);
1243
 
1244
 
1245
    $display ("test 32 LSB data values starting with positive disparity");
1246
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h020;
1247
                      test_data[8:0] = test_data[8:0] + 9'h001)
1248
    begin
1249
      check (1, test_data[7:0], 1'b0);
1250
    end
1251
 
1252
    $display ("test 8 MSB data values starting with positive disparity");
1253
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1254
                      test_data[8:0] = test_data[8:0] + 9'h001)
1255
    begin
1256
      check (1, (test_data[2:0] << 5) | 5'h03, 1'b0);
1257
    end
1258
 
1259
    $display ("test 8 MSB data values starting with positive disparity");
1260
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1261
                      test_data[8:0] = test_data[8:0] + 9'h001)
1262
    begin
1263
      check (1, (test_data[2:0] << 5) | 5'h0B, 1'b0);  // 11
1264
    end
1265
 
1266
    $display ("test 8 MSB data values starting with positive disparity");
1267
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1268
                      test_data[8:0] = test_data[8:0] + 9'h001)
1269
    begin
1270
      check (1, (test_data[2:0] << 5) | 5'h11, 1'b0);  // 17
1271
    end
1272
 
1273
    $display ("test control starting with positive disparity");
1274
    check (1, `K_23_7, 1'b1);
1275
    check (1, `K_27_7, 1'b1);
1276
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h008;
1277
                      test_data[8:0] = test_data[8:0] + 9'h001)
1278
    begin
1279
      check (1, `K_28_0 | (test_data[2:0] << 5), 1'b1);
1280
    end
1281
    check (1, `K_29_7, 1'b1);
1282
    check (1, `K_30_7, 1'b1);
1283
 
1284
//    $display ("invalid control character with positive disparity");
1285
//    check (1, 8'h0, 1'b1);
1286
 
1287 23 bbeaver
    limit[8:0] = 9'h100;  # 1;
1288
 
1289
    $display ("trying all byte pairs starting with negative disparity");
1290
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
1291
                      test_data[8:0] = test_data[8:0] + 9'h001)
1292
    begin
1293
      for (test_data_second[8:0] = 9'h000; test_data_second[8:0] < limit[8:0];
1294
                        test_data_second[8:0] = test_data_second[8:0] + 9'h001)
1295
      begin
1296
        check_pair (0, test_data[7:0], test_data_second[7:0], 1'b0, 1'b0);
1297
      end
1298
    end
1299
 
1300
    $display ("trying all controls then bytes with negative disparity");
1301 24 bbeaver
    $display ("This finds 24 unexpected extra singular commas when sending K_28_7");
1302 23 bbeaver
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
1303
                      test_data[8:0] = test_data[8:0] + 9'h001)
1304
    begin
1305 24 bbeaver
      for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
1306
           test_data_second[3:0] = test_data_second[3:0] + 4'h1)
1307
      begin
1308
        check_pair (0, pick_control_byte(test_data_second[3:0]), test_data[7:0], 1'b1,
1309
                         (test_data_second[3:0] == 4'h3)
1310
                       | (test_data_second[3:0] == 4'h7)
1311
                       | (test_data_second[3:0] == 4'h9) );
1312
      end
1313 23 bbeaver
    end
1314
 
1315
    $display ("trying all bytes then controls with negative disparity");
1316 24 bbeaver
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
1317
                      test_data[8:0] = test_data[8:0] + 9'h001)
1318
    begin
1319
      for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
1320
           test_data_second[3:0] = test_data_second[3:0] + 4'h1)
1321
      begin
1322
        check_pair_2 (0, test_data[7:0], pick_control_byte(test_data_second[3:0]),
1323
                       1'b0, 1'b0,
1324
                       1'b1,   (test_data_second[3:0] == 4'h3)
1325
                             | (test_data_second[3:0] == 4'h7)
1326
                             | (test_data_second[3:0] == 4'h9) );
1327
      end
1328
    end
1329
 
1330 23 bbeaver
    $display ("trying all controls then controls with negative disparity");
1331 24 bbeaver
    $display ("This finds 8 unexpected extra singular commas when sending K_28_7");
1332
    for (test_data[3:0] = 9'h000; test_data[3:0] < 4'hC;
1333
                      test_data[3:0] = test_data[3:0] + 4'h1)
1334
    begin
1335
      for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
1336
           test_data_second[3:0] = test_data_second[3:0] + 4'h1)
1337
      begin
1338
        check_pair_2 (0, pick_control_byte(test_data[3:0]),
1339
                         pick_control_byte(test_data_second[3:0]),
1340
                       1'b1,   (test_data[3:0] == 4'h3)
1341
                             | (test_data[3:0] == 4'h7)
1342
                             | (test_data[3:0] == 4'h9),
1343
                       1'b1,   (test_data_second[3:0] == 4'h3)
1344
                             | (test_data_second[3:0] == 4'h7)
1345
                             | (test_data_second[3:0] == 4'h9) );
1346
      end
1347
    end
1348 23 bbeaver
 
1349
    $display ("trying all byte pairs starting with positive disparity");
1350
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
1351
                      test_data[8:0] = test_data[8:0] + 9'h001)
1352
    begin
1353
      for (test_data_second[8:0] = 9'h000; test_data_second[8:0] < limit[8:0];
1354
                        test_data_second[8:0] = test_data_second[8:0] + 9'h001)
1355
      begin
1356
        check_pair (1, test_data[7:0], test_data_second[7:0], 1'b0, 1'b0);
1357
      end
1358
    end
1359
 
1360
    $display ("trying all controls then bytes with positive disparity");
1361 24 bbeaver
    $display ("This finds 24 unexpected extra singular commas when sending K_28_7");
1362 23 bbeaver
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
1363
                      test_data[8:0] = test_data[8:0] + 9'h001)
1364
    begin
1365 24 bbeaver
      for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
1366
           test_data_second[3:0] = test_data_second[3:0] + 4'h1)
1367
      begin
1368
        check_pair (1, pick_control_byte(test_data_second[3:0]), test_data[7:0], 1'b1,
1369
                         (test_data_second[3:0] == 4'h3)
1370
                       | (test_data_second[3:0] == 4'h7)
1371
                       | (test_data_second[3:0] == 4'h9) );
1372
      end
1373 23 bbeaver
    end
1374
 
1375
    $display ("trying all bytes then controls with positive disparity");
1376 24 bbeaver
    for (test_data[8:0] = 9'h000; test_data[8:0] < 9'h100;
1377
                      test_data[8:0] = test_data[8:0] + 9'h001)
1378
    begin
1379
      for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
1380
           test_data_second[3:0] = test_data_second[3:0] + 4'h1)
1381
      begin
1382
        check_pair_2 (1, test_data[7:0], pick_control_byte(test_data_second[3:0]),
1383
                       1'b0, 1'b0,
1384
                       1'b1,   (test_data_second[3:0] == 4'h3)
1385
                             | (test_data_second[3:0] == 4'h7)
1386
                             | (test_data_second[3:0] == 4'h9) );
1387
      end
1388
    end
1389
 
1390 23 bbeaver
    $display ("trying all controls then controls with positive disparity");
1391 24 bbeaver
    $display ("This finds 8 unexpected extra singular commas when sending K_28_7");
1392
    for (test_data[3:0] = 9'h000; test_data[3:0] < 4'hC;
1393
                      test_data[3:0] = test_data[3:0] + 4'h1)
1394
    begin
1395
      for (test_data_second[3:0] = 4'h0; test_data_second[3:0] < 4'hC;
1396
           test_data_second[3:0] = test_data_second[3:0] + 4'h1)
1397
      begin
1398
        check_pair_2 (1, pick_control_byte(test_data[3:0]),
1399
                         pick_control_byte(test_data_second[3:0]),
1400
                       1'b1,   (test_data[3:0] == 4'h3)
1401
                             | (test_data[3:0] == 4'h7)
1402
                             | (test_data[3:0] == 4'h9),
1403
                       1'b1,   (test_data_second[3:0] == 4'h3)
1404
                             | (test_data_second[3:0] == 4'h7)
1405
                             | (test_data_second[3:0] == 4'h9) );
1406
      end
1407
    end
1408 18 bbeaver
  end
1409
 
1410
encode_8b_10b encode_8b_10b (
1411
  .eight_bit_data_or_control_in (eight_bit_data_or_control_in[7:0]),
1412
  .input_is_control           (input_is_control),
1413 22 bbeaver
  .mess_up_link_disparity     (mess_up_link_disparity),
1414 18 bbeaver
  .ten_bit_encoded_data_out   (ten_bit_encoded_data_out[9:0]),
1415
  .invalid_control            (invalid_control),
1416
  .clk                        (clk),
1417
  .reset                      (reset)
1418
);
1419
 
1420
decode_10b_8b decode_10b_8b (
1421 19 bbeaver
  .ten_bit_encoded_data_in    (ten_bit_encoded_data_out[9:0]),
1422 18 bbeaver
  .eight_bit_data_or_control_out (eight_bit_data_or_control_out[7:0]),
1423
  .output_is_control          (output_is_control),
1424 22 bbeaver
  .invalid_encoded_data       (invalid_encoded_data),
1425 18 bbeaver
  .clk                        (clk),
1426
  .reset                      (reset)
1427
);
1428
endmodule
1429
`endif  // TEST_8B_10B
1430
 
1431 19 bbeaver
// `define DISCOVER_WHICH_CODES_ARE_ILLEGAL
1432
`ifdef DISCOVER_WHICH_CODES_ARE_ILLEGAL
1433 18 bbeaver
module figure_out_error_patterns;
1434 22 bbeaver
 
1435
// NOTE: For the purpose of comparing with the patent, this exploration
1436
//         module uses the notation that the LEFTMOST BIT is the LSB.
1437
//       All other modules use the more normal Rightmost Bit == bit 0 == LSB
1438
 
1439 18 bbeaver
  reg    [10:0] i;
1440
 
1441
  reg    [9:0] full_addr;
1442 19 bbeaver
  reg    [4095:0] valid;  // storage
1443
  reg    [4095:0] invalid;  // storage
1444 18 bbeaver
 
1445
task do_one;
1446
  input  [3:0] high_addr;
1447
  begin
1448
    full_addr[3:0] = high_addr[3:0];  // note LSB to left
1449 19 bbeaver
    valid[full_addr[9:0]] = 1'b1;
1450 18 bbeaver
  end
1451
endtask
1452
 
1453 19 bbeaver
task mark_both;
1454 18 bbeaver
  begin
1455
// both
1456
    do_one (4'b1001);
1457
    do_one (4'b0101);
1458
    do_one (4'b1010);
1459
    do_one (4'b0110);
1460
  end
1461
endtask
1462
 
1463
// The alternate Data encoding D.x.A7 is used in the case
1464
//   that e = i = 0 and positive running disparity,
1465
//   or   e = i = 1 and negative running disparity,
1466
//   or a Control signal is being sent,
1467
//   all while encoding 7 in the MSB.
1468
 
1469 19 bbeaver
task mark_positive;
1470 18 bbeaver
  begin
1471
// positive list
1472
    do_one (4'b0100);
1473
    do_one (4'b0011);
1474
    do_one (4'b0010);
1475
    if (full_addr[5:4] != 2'b00)
1476
      do_one (4'b0001);  // P
1477
    else
1478
      do_one (4'b1000);  // A
1479
  end
1480
endtask
1481
 
1482 19 bbeaver
task mark_negative;
1483 18 bbeaver
  begin
1484
// negative list
1485
    do_one (4'b1011);
1486
    do_one (4'b1100);
1487
    do_one (4'b1101);
1488
    if (full_addr[5:4] != 2'b11)
1489
      do_one (4'b1110);  // P
1490
    else
1491
      do_one (4'b0111);  // A
1492
  end
1493
endtask
1494
 
1495 19 bbeaver
task mark_all;
1496 18 bbeaver
  begin
1497 19 bbeaver
    mark_positive;
1498
    mark_negative;
1499
    mark_both;
1500 18 bbeaver
  end
1501
endtask
1502
 
1503 19 bbeaver
task mark;
1504 18 bbeaver
  input  [5:0] val;
1505
  input   type;
1506
  integer type;
1507
 
1508
  begin
1509
    full_addr[9:4] = val[5:0];  // note LSB to left
1510
    if (type == 0)
1511
    begin
1512 19 bbeaver
      mark_all;
1513 18 bbeaver
    end
1514
    else if (type == 1)
1515
    begin
1516 19 bbeaver
      mark_positive;
1517
      mark_both;
1518 18 bbeaver
    end
1519
    else
1520
    begin
1521 19 bbeaver
      mark_negative;
1522
      mark_both;
1523 18 bbeaver
    end
1524
  end
1525
endtask
1526
 
1527
initial
1528
  begin
1529
 
1530
// Clear all bits
1531
    for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
1532
    begin
1533 19 bbeaver
      valid[i[9:0]] = 1'b0;
1534
      invalid[full_addr[9:0]] = 1'b0;
1535 18 bbeaver
    end
1536
 
1537 19 bbeaver
// Mark patterns which are parts of valid codes
1538
    mark (6'b110001, 0);
1539
    mark (6'b101001, 0);
1540
    mark (6'b011001, 0);
1541
    mark (6'b100101, 0);
1542
    mark (6'b010101, 0);
1543
    mark (6'b110100, 0);
1544
    mark (6'b001101, 0);
1545
    mark (6'b101100, 0);
1546
    mark (6'b011100, 0);
1547
    mark (6'b100011, 0);
1548
    mark (6'b010011, 0);
1549
    mark (6'b110010, 0);
1550
    mark (6'b001011, 0);
1551
    mark (6'b101010, 0);
1552
    mark (6'b011010, 0);
1553
    mark (6'b100110, 0);
1554
    mark (6'b010110, 0);
1555
    mark (6'b001110, 0);
1556 18 bbeaver
 
1557 19 bbeaver
    mark (6'b011000, -1);
1558
    mark (6'b100010, -1);
1559
    mark (6'b010010, -1);
1560
    mark (6'b001010, -1);
1561
    mark (6'b111000, -1);
1562
    mark (6'b000110, -1);
1563
    mark (6'b101000, -1);
1564
    mark (6'b100100, -1);
1565
    mark (6'b000101, -1);
1566
    mark (6'b001100, -1);
1567
    mark (6'b001001, -1);
1568
    mark (6'b010001, -1);
1569
    mark (6'b100001, -1);
1570
    mark (6'b010100, -1);
1571 18 bbeaver
 
1572 19 bbeaver
    mark (6'b100111, +1);
1573
    mark (6'b011101, +1);
1574
    mark (6'b101101, +1);
1575
    mark (6'b110101, +1);
1576
    mark (6'b000111, +1);
1577
    mark (6'b111001, +1);
1578
    mark (6'b010111, +1);
1579
    mark (6'b011011, +1);
1580
    mark (6'b111010, +1);
1581
    mark (6'b110011, +1);
1582
    mark (6'b110110, +1);
1583
    mark (6'b101110, +1);
1584
    mark (6'b011110, +1);
1585
    mark (6'b101011, +1);
1586 18 bbeaver
 
1587 19 bbeaver
// Mark patterns which are control codes.
1588
    valid[ 10'b111010_1000] = 1'b1;
1589
    valid[ 10'b110110_1000] = 1'b1;
1590
    valid[ 10'b101110_1000] = 1'b1;
1591
    valid[ 10'b011110_1000] = 1'b1;
1592
 
1593
    valid[ 10'b001111_0100] = 1'b1;
1594
    valid[ 10'b001111_1001] = 1'b1;
1595
    valid[ 10'b001111_0101] = 1'b1;
1596
    valid[ 10'b001111_0011] = 1'b1;
1597
    valid[ 10'b001111_0010] = 1'b1;
1598
    valid[ 10'b001111_1010] = 1'b1;
1599
    valid[ 10'b001111_0110] = 1'b1;
1600
    valid[ 10'b001111_1000] = 1'b1;
1601
 
1602
    valid[~10'b111010_1000] = 1'b1;
1603
    valid[~10'b110110_1000] = 1'b1;
1604
    valid[~10'b101110_1000] = 1'b1;
1605
    valid[~10'b011110_1000] = 1'b1;
1606
 
1607
    valid[~10'b001111_0100] = 1'b1;
1608
    valid[~10'b001111_1001] = 1'b1;
1609
    valid[~10'b001111_0101] = 1'b1;
1610
    valid[~10'b001111_0011] = 1'b1;
1611
    valid[~10'b001111_0010] = 1'b1;
1612
    valid[~10'b001111_1010] = 1'b1;
1613
    valid[~10'b001111_0110] = 1'b1;
1614
    valid[~10'b001111_1000] = 1'b1;
1615
 
1616 18 bbeaver
    for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
1617
    begin
1618
// Get rid of patterns in the 6 LSB with less than 2 or greater than 4 bits set.
1619
      if ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) < 2)
1620
      begin
1621 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1622 18 bbeaver
      end
1623
      if ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) > 4)
1624
      begin
1625 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1626 18 bbeaver
      end
1627
// Get rid of patterns in the 4 MSB with less than 1 or greater than 3 bits set.
1628
      if ((i[3:0] == 4'h0) | (i[3:0] == 4'hF))
1629
      begin
1630 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1631 18 bbeaver
      end
1632
// Get rid of total patterns with less than 4 or greater than 6 bits set.
1633
      if ((i[0] + i[1] + i[2] + i[3] + i[4] + i[5] + i[6] + i[7] + i[8] + i[9]) < 4)
1634
      begin
1635 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1636 18 bbeaver
      end
1637
      if ((i[0] + i[1] + i[2] + i[3] + i[4] + i[5] + i[6] + i[7] + i[8] + i[9]) > 6)
1638
      begin
1639 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1640 18 bbeaver
      end
1641
// Get rid of patterns with the 4 LSB all 0 or all 1
1642
      if ((i[9:6] == 4'b0000) | (i[9:6] == 4'b1111))
1643
      begin
1644 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1645 18 bbeaver
      end
1646 22 bbeaver
// Get rid of patterns which use D.7.y with the wrong disparity.  8
1647 18 bbeaver
      if ((i[9:4] == 6'b111000) & (i[3] + i[2] + i[1] + i[0] == 1))  // minus then minus
1648
      begin
1649 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1650 18 bbeaver
      end
1651
      if ((i[9:4] == 6'b000111) & (i[3] + i[2] + i[1] + i[0] == 3))  // plus then plus
1652
      begin
1653 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1654 18 bbeaver
      end
1655 22 bbeaver
// Get rid of patterns which use D.x.3 with the wrong disparity.  28
1656 18 bbeaver
      if (   (i[3:0] == 4'b0011)
1657
           & ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) == 2))
1658
      begin
1659 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1660 18 bbeaver
      end
1661
      if (   (i[3:0] == 4'b1100)
1662
           & ((i[9] + i[8] + i[7] + i[6] + i[5] + i[4]) == 4))
1663
      begin
1664 19 bbeaver
        invalid[i[9:0]] = 1'b1;
1665 18 bbeaver
      end
1666 22 bbeaver
    end
1667
 
1668
// Get rid of case when D.x.3 and D.7.y are used together as D.7.3
1669
    valid[10'b111000_0011] = 1'b1;
1670
    valid[10'b000111_1100] = 1'b1;
1671
 
1672
    for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
1673
    begin
1674
// Get rid of non-control codes which use alternate encoding inappropriately.  32
1675
// These are all the data items except 23, 27, 29, and 30 which do not end in
1676 18 bbeaver
//   00 or 11 as the MSB.  This excludes control codes, which use alternate encoding.
1677
      if (   (i[9:4] != 6'b111010) & (i[9:4] != 6'b000101)  // 23
1678
           & (i[9:4] != 6'b110110) & (i[9:4] != 6'b001001)  // 27
1679
           & (i[9:4] != 6'b101110) & (i[9:4] != 6'b010001)  // 29
1680
           & (i[9:4] != 6'b011110) & (i[9:4] != 6'b100001)  // 30
1681 22 bbeaver
           & (i[9:4] != 6'b001111) & (i[9:4] != 6'b110000)  // K28
1682
           & (i[9:4] != 6'b110100)  // 11
1683
           & (i[9:4] != 6'b101100)  // 13
1684
           & (i[9:4] != 6'b011100)  // 14
1685
           & (i[9:4] != 6'b100011)  // 17
1686
           & (i[9:4] != 6'b010011)  // 18
1687
           & (i[9:4] != 6'b001011)  // 20
1688
         )
1689 18 bbeaver
      begin
1690
        if ((i[3:0] == 4'b0111) | (i[3:0] == 4'b1000))
1691
        begin
1692 22 bbeaver
          invalid[i[9:0]] = 1'b1;  // not a candidate for alternate D7 at all
1693
        end
1694
      end
1695
 
1696
      if (   (i[9:4] == 6'b110000)  // K28
1697
           | (i[9:4] == 6'b001111)  // K28
1698
           | (i[9:4] == 6'b110100)  // 11
1699
           | (i[9:4] == 6'b101100)  // 13
1700
           | (i[9:4] == 6'b011100)  // 14
1701
         )
1702
      begin
1703
        if (i[3:0] == 4'b0001)  // cant use normal +
1704
        begin
1705 19 bbeaver
          invalid[i[9:0]] = 1'b1;
1706 18 bbeaver
        end
1707
      end
1708
 
1709 22 bbeaver
      if (   (i[9:4] == 6'b100011)  // 17
1710
           | (i[9:4] == 6'b010011)  // 18
1711
           | (i[9:4] == 6'b001011)  // 20
1712
         )
1713
      begin
1714
        if (i[3:0] == 4'b1000)  // cant use alternate +
1715
        begin
1716
          invalid[i[9:0]] = 1'b1;
1717
        end
1718
      end
1719 18 bbeaver
 
1720 22 bbeaver
      if (   (i[9:4] == 6'b110000)  // K28
1721
           | (i[9:4] == 6'b001111)  // K28
1722
           | (i[9:4] == 6'b100011)  // 17
1723
           | (i[9:4] == 6'b010011)  // 18
1724
           | (i[9:4] == 6'b001011)  // 20
1725
         )
1726
      begin
1727
        if (i[3:0] == 4'b1110)  // cant use normal -
1728
        begin
1729
          invalid[i[9:0]] = 1'b1;
1730
        end
1731
      end
1732 18 bbeaver
 
1733 22 bbeaver
      if (   (i[9:4] == 6'b110100)  // 11
1734
           | (i[9:4] == 6'b101100)  // 13
1735
           | (i[9:4] == 6'b011100)  // 14
1736
         )
1737
      begin
1738
        if (i[3:0] == 4'b0111)  // cant use alternate -
1739
        begin
1740
          invalid[i[9:0]] = 1'b1;
1741
        end
1742
      end
1743
    end
1744 18 bbeaver
 
1745
    $display ("LSB is to the left");
1746
    for (i[10:0] = 11'h000; i[10:0] < 11'h400; i[10:0] = i[10:0] + 11'h001)
1747
    begin
1748 19 bbeaver
      if ((valid[i[9:0]] !== 1'b1) & (invalid[i[9:0]] !== 1'b1))
1749 18 bbeaver
      begin
1750
        $display ("not set %b", i[9:0]);
1751
      end
1752 19 bbeaver
      if ((valid[i[9:0]] === 1'b1) & (invalid[i[9:0]] === 1'b1))
1753
      begin
1754
        $display ("both set %b", i[9:0]);
1755
      end
1756 18 bbeaver
    end
1757
 
1758
  end
1759
endmodule
1760 19 bbeaver
`endif  // DISCOVER_WHICH_CODES_ARE_ILLEGAL

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.