decoder_8b10b_mod.v 11.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
// Copyright 2007 Altera Corporation. All rights reserved.  
// Altera products are protected under numerous U.S. and foreign patents, 
// maskwork rights, copyrights and other intellectual property laws.  
//
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design 
// License Agreement (either as signed by you or found at www.altera.com).  By
// using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation.  In the event that you do
// not agree with such terms and conditions, you may not use the reference 
// design file and please promptly destroy any copies you have made.
//
// This reference design file is being provided on an "as-is" basis and as an 
// accommodation and therefore all warranties, representations or guarantees of 
// any kind (whether express, implied or statutory) including, without 
// limitation, warranties of merchantability, non-infringement, or fitness for
// a particular purpose, are specifically disclaimed.  By making this reference
// design file available, Altera expressly does not recommend, suggest or 
// require that this reference design file be used in combination with any 
// other product not provided by Altera.
/////////////////////////////////////////////////////////////////////////////

// baeckler - 04-10-2006
// an 8b10b decoder, based on files from Martin R and IBM paper


//=============================== MBM (23/08/16) ==========================\\
// Comment: - Although from Altera, this module is VENDOR AGNOSTIC, so it  \\
//            can be synthesized for any FPGA model.                       \\
//          - The Device specific (Stratix V) part of this module has been \\
//            removed in order to simplify the readability of the code.    \\
//=========================================================================\\


module decoder_8b10b (
    clk,
    rst,            
    din_ena,            // 10b data ready
    din_dat,            // 10b data input
    din_rd,             // running disparity input
    dout_val,           // data out valid       
    dout_dat,           // data out
    dout_k,             // special code
    dout_kerr,          // coding mistake detected
    dout_rderr,         // running disparity mistake detected
    dout_rdcomb,        // running disparity output (comb)
    dout_rdreg          // running disparity output (reg)
);

parameter RDERR = 1;
parameter KERR = 1;

input        clk;
input        rst;
input        din_ena;
input  [9:0] din_dat;
input        din_rd;
output       dout_val;
output [7:0] dout_dat;
output       dout_k;
output       dout_kerr;
output       dout_rderr;
output       dout_rdcomb;
output       dout_rdreg;

//reg [9:0] din_dat;

reg          dout_val;
reg    [7:0] dout_dat;
reg          dout_k;
reg          dout_kerr;
reg          dout_rderr;
reg          dout_rdreg;

wire a = din_dat[0];
wire b = din_dat[1];
wire c = din_dat[2];
wire d = din_dat[3];
wire e = din_dat[4];
wire i = din_dat[5];
wire f = din_dat[6];
wire g = din_dat[7];
wire h = din_dat[8];
wire j = din_dat[9];

//classification
wire P04 = (!a & !b & !c & !d);
wire P13 = (!a & !b & !c & d) | (!a & !b & c & !d) | (!a & b & !c & !d) | (a & !b & !c & !d);
wire P22 = (!a & !b & c & d) | (!a & b & c & !d) | (a & b & !c & !d) | (a & !b & c & !d) | (a & !b & !c & d)  | (!a & b & !c & d);
wire P31 = (a & b & c & !d) | (a & b & !c & d) | (a & !b & c & d) | (!a & b & c & d);
wire P40 = (a & b & c & d);

////////////////////////////////////////////////
// data outputs
////////////////////////////////////////////////

wire A = (P22 & !b & !c & !(e^i)) ? !a :
         (P31 & i) ? !a :
         (P13 & d & e & i) ? !a :
         (P22 & !a & !c & !(e^i)) ? !a :
         (P13 & !e) ? !a :
         (a & b & e & i) ? !a :
         (!c & !d & !e & !i) ? !a :
         a;
         
wire B = (P22 & b & c & !(e^i)) ? !b :
         (P31 & i) ? !b :
         (P13 & d & e & i) ? !b :
         (P22 & a & c & !(e^i)) ? !b :
         (P13 & !e) ? !b :
         (a & b & e & i) ? !b :
         (!c & !d & !e & !i) ? !b :
         b;
         
wire C = (P22 & b & c & !(e^i)) ? !c :
         (P31 & i) ? !c :
         (P13 & d & e & i) ? !c :
         (P22 & !a & !c & !(e^i)) ? !c :
         (P13 & !e) ? !c :
         (!a & !b & !e & !i) ? !c :
         (!c & !d & !e & !i) ? !c :
         c;
         
wire D = (P22 & !b & !c & !(e^i)) ? !d :
         (P31 & i) ? !d :
         (P13 & d & e & i) ? !d :
         (P22 & a & c & !(e^i)) ? !d :
         (P13 & !e) ? !d :
         (a & b & e & i) ? !d :
         (!c & !d & !e & !i) ? !d :
         d;
wire E = (P22 & !b & !c & !(e^i)) ? !e :
         (P13 & !i) ? !e :
         (P13 & d & e & i) ? !e :
         (P22 & !a & !c & !(e^i)) ? !e :
         (P13 & !e) ? !e :
         (!a & !b & !e & !i) ? !e :
         (!c & !d & !e & !i) ? !e :
         e;
         
wire F = (f & h & j) ? !f :
         (!c & !d & !e & !i & (h^j)) ? !f :
         (!f & !g & h & j) ? !f :
         (f & g & j) ? !f :
         (!f & !g & !h) ? !f :
         (g & h & j) ? !f :
         f;
         
wire G = (!f & !h & !j) ? !g :
         (!c & !d & !e & !i & (h^j)) ? !g :
         (!f & !g & h & j) ? !g :
         (f & g & j) ? !g :
         (!f & !g & !h) ? !g :
         (!g & !h & !j) ? !g :
         g;
         
wire H = (f & h & j) ? !h :
         (!c & !d & !e & !i & (h^j)) ? !h :
         (!f & !g & h & j) ? !h :
         (f & g & j) ? !h :
         (!f & !g & !h) ? !h :
         (!g & !h & !j) ? !h :
         h;

wire K = (c & d & e & i) |
         (!c & !d & !e & !i) |
         (P13 & !e & i & g & h & j) |
         (P31 & e & !i & !g & !h & !j);

////////////////////////////////////////////////
//running disparity - generate and err check
////////////////////////////////////////////////

wire rd1n = (P04) ? 1 :
            (P13 & !(e & i)) ? 1 :
            (P22 & !e & !i) ? 1 :
            (P13 & d & e & i) ? 1 :
            0 /* synthesis keep */;
            
wire rd1p = (P40) ? 1 :
            (P31 & !(!e & !i)) ? 1 :
            (P22 & e & i) ? 1 :
            (P31 & !d & !e & !i) ? 1 :
            0 /* synthesis keep */;
            
wire rd1e = (P13 & !d & e & i) ? 1 :
            (P22 & (e ^ i)) ? 1 :
            (P31 & d & !e & !i) ? 1 :
            0 /* synthesis keep */;

wire rd1_err = (!din_rd & rd1n) | (din_rd & rd1p);

/////////////////////////////
// factored rd1 generation
/////////////////////////////

wire [63:0] rd1_when_din_rd_0_mask = 64'hffe8e880e8808000;
wire rd1_when_din_rd_0 = rd1_when_din_rd_0_mask[din_dat[5:0]] /* synthesis keep */;
wire [63:0] rd1_when_din_rd_1_mask = 64'hfffefee8fee8e800;
wire rd1_when_din_rd_1 = rd1_when_din_rd_1_mask[din_dat[5:0]] /* synthesis keep */;
wire rd1 = din_rd ? rd1_when_din_rd_1 : rd1_when_din_rd_0;

wire rd2n = (!f & !g & !h) ? 1 :
            (!f & !g & !j) ? 1 :
            (!f & !h & !j) ? 1 :
            (!g & !h & !j) ? 1 :
            (!f & !g & h & j) ? 1 :
            0 /* synthesis keep */;
            
wire rd2p = (f & g & h) ? 1 :
            (f & g & j) ? 1 :
            (f & h & j) ? 1 :
            (g & h & j) ? 1 :
            (f & g & !h & !j) ? 1 :
            0 /* synthesis keep */;
            
wire rd2e = ((f ^ g) & (h ^ j)) ? 1 :
            0;

wire rd2_err = (!rd1 & rd2n) | (rd1 & rd2p);

// these two conditions appear in rd2p and rd2n with the
// opposite associated rdcomb output.
wire dout_rdcomb_special = (!f & !g &  h &  j) |
                            ( f &  g & !h & !j) /* synthesis keep */;

wire dout_rdcomb = (rd2p) ? !dout_rdcomb_special :
                   (rd2n) ? dout_rdcomb_special :
                   rd1;

////////////////////////////////////////////////
// K error check - this is by far the most
//   complex expression in the decoder. 
//   It appears to require depth 3.  Please let
//   me know if you identify a depth 2 mapping.
////////////////////////////////////////////////

wire k_err;

assign k_err = //5b6b errors

     (P04) ? 1 :
     (P13 & !e & !i) ? 1 :
     (P31 & e & i) ? 1 :
     (P40) ? 1 :
     //3b4b errors
     ( f &  g &  h &  j) ? 1 :
     (!f & !g & !h & !j) ? 1 :

     //any 2nd phase rd error, except if rd1 is even
     (rd2_err & !rd1e) ? 1 :

     // + some odd ones, dx.7 - specials ...
     // d11.7,d13.7,d14.7,d17.7,d18.7,d20.7  use 1000/0111
     // k23.7,k27.7,k29.7,k30.7 are legal    use 1000/0111
     // other x.7                            use 0001/1110

     // P22 & xxxx01 1110 - ok, d12.7
     // P22 & xxxx10 1110 - ok, d28.7
     // P22 & 011000 1110 - ok, d0.7
     // P22 & 101000 1110 - ok, d15.7
     // P22 & 100100 1110 - ok, d16.7
     // P22 & 001100 1110 - ok, d24.7
     // P22 & 010100 1110 - ok, d31.7
     // P22 & 110000 1110 - illegal
     //       xxxx11 1110 - illegal
     ( a &  b & !c & !d & !e & !i &  f &  g &  h & !j) ? 1 :
     (                     e &  i &  f &  g &  h & !j) ? 1 :

     // P22 & xxxx01 0001 - ok, d6.7
     // P31 & xxxx01 0001 - ok, d1.7
     // P31 & xxxx10 0001 - ok, d23.7
     // P22 & xxxx10 0001 - ok, d19.7
     // P13 & xxxx11 0001 - ok, d7.7
     //       110011 0001 - ok, d24.7
     //       101011 0001 - ok, d31.7
     //       011011 0001 - ok, d16.7
     //       100111 0001 - ok, d0.7
     //       010111 0001 - ok, d15.7
     //       001111 0001 - illegal
     //       xxxx00 0001 - illegal
     (!a & !b &  c &  d &  e &  i & !f & !g & !h &  j) ? 1 :
     (                    !e & !i & !f & !g & !h &  j) ? 1 :

     //       110000 0111 - ok, k28.7
     // P13 & xxxx01 0111 = ok, kxx.7
     //       100011 0111 = ok, d17.7
     //       010011 0111 = ok, d18.7
     //       001011 0111 = ok, d20.7
     //       000111 0111 = illegal (rderr)
     // else  xxxxxx 0111 - illegal
     (!(P22 & !c & !d)        & !e & !i & !f & g & h & j) ? 1 :
     (!(P13)                  & !e &  i & !f & g & h & j) ? 1 :
     (!(P13 & (a | b | c))    &  e &  i & !f & g & h & j) ? 1 :
     (                           e & !i & !f & g & h & j) ? 1 :

     //       001111 1000 - ok, k28.7
     // P31 & xxxx10 1000 = ok, kxx.7
     //       110100 1000 - ok, d11.7
     //       101100 1000 - ok, d13.7
     //       011100 1000 - ok, d14.7
     //       111000 1000 - illegal (rderr)
     // else  xxxxxx 1000 - illegal
     (!(P22 & c & d)          &  e &  i & f & !g & !h & !j) ? 1 :
     (!(P31)                  &  e & !i & f & !g & !h & !j) ? 1 :
     (!(P31 & (!a | !b | !c)) & !e & !i & f & !g & !h & !j) ? 1 :
     (                          !e &  i & f & !g & !h & !j) ? 1 :

     0;

////////////////////////////////////////////////
// output registers
////////////////////////////////////////////////

always @(posedge clk or posedge rst)
begin
    if (rst)
    begin
        dout_k <= 0;
        dout_val <= 0;
        dout_dat <= 0;
        dout_rdreg <= 0;
        dout_rderr <= 0;
        dout_kerr <= 0;
    end
    else
    begin
        dout_val <= 0;
        if (din_ena)
        begin
            dout_k <= K;
            dout_val <= din_ena;
            dout_dat <= {H,G,F,E,D,C,B,A};
            dout_rdreg <= dout_rdcomb;
            dout_rderr <= (RDERR) ? (rd1_err | rd2_err) : 0;
            dout_kerr <= (KERR) ? k_err : 0;
        end
    end
end

endmodule