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

Subversion Repositories xge_mac

[/] [xge_mac/] [trunk/] [rtl/] [verilog/] [rx_enqueue.v] - Blame information for rev 23

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 antanguay
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "rx_enqueue.v"                                    ////
4
////                                                              ////
5
////  This file is part of the "10GE MAC" project                 ////
6
////  http://www.opencores.org/cores/xge_mac/                     ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - A. Tanguay (antanguay@opencores.org)                  ////
10
////                                                              ////
11
//////////////////////////////////////////////////////////////////////
12
////                                                              ////
13
//// Copyright (C) 2008 AUTHORS. All rights reserved.             ////
14
////                                                              ////
15
//// This source file may be used and distributed without         ////
16
//// restriction provided that this copyright statement is not    ////
17
//// removed from the file and that any derivative work contains  ////
18
//// the original copyright notice and the associated disclaimer. ////
19
////                                                              ////
20
//// This source file is free software; you can redistribute it   ////
21
//// and/or modify it under the terms of the GNU Lesser General   ////
22
//// Public License as published by the Free Software Foundation; ////
23
//// either version 2.1 of the License, or (at your option) any   ////
24
//// later version.                                               ////
25
////                                                              ////
26
//// This source is distributed in the hope that it will be       ////
27
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
28
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
29
//// PURPOSE.  See the GNU Lesser General Public License for more ////
30
//// details.                                                     ////
31
////                                                              ////
32
//// You should have received a copy of the GNU Lesser General    ////
33
//// Public License along with this source; if not, download it   ////
34
//// from http://www.opencores.org/lgpl.shtml                     ////
35
////                                                              ////
36
//////////////////////////////////////////////////////////////////////
37
 
38
 
39
`include "defines.v"
40
 
41
module rx_enqueue(/*AUTOARG*/
42
  // Outputs
43 12 antanguay
  rxdfifo_wdata, rxdfifo_wstatus, rxdfifo_wen, rxhfifo_ren,
44
  rxhfifo_wdata, rxhfifo_wstatus, rxhfifo_wen, local_fault_msg_det,
45
  remote_fault_msg_det, status_crc_error_tog,
46
  status_fragment_error_tog, status_rxdfifo_ovflow_tog,
47 23 antanguay
  status_pause_frame_rx_tog, status_good_frame_rx_tog,
48
  status_good_frame_rx_size,
49 2 antanguay
  // Inputs
50 12 antanguay
  clk_xgmii_rx, reset_xgmii_rx_n, xgmii_rxd, xgmii_rxc, rxdfifo_wfull,
51
  rxhfifo_rdata, rxhfifo_rstatus, rxhfifo_rempty,
52 2 antanguay
  rxhfifo_ralmost_empty
53
  );
54
 
55
`include "CRC32_D64.v"
56
`include "CRC32_D8.v"
57
`include "utils.v"
58
 
59
input         clk_xgmii_rx;
60
input         reset_xgmii_rx_n;
61 21 antanguay
 
62 2 antanguay
input  [63:0] xgmii_rxd;
63
input  [7:0]  xgmii_rxc;
64
 
65
input         rxdfifo_wfull;
66 21 antanguay
 
67 2 antanguay
input  [63:0] rxhfifo_rdata;
68
input  [7:0]  rxhfifo_rstatus;
69
input         rxhfifo_rempty;
70
input         rxhfifo_ralmost_empty;
71
 
72
output [63:0] rxdfifo_wdata;
73
output [7:0]  rxdfifo_wstatus;
74 21 antanguay
output        rxdfifo_wen;
75 2 antanguay
 
76
output        rxhfifo_ren;
77
 
78
output [63:0] rxhfifo_wdata;
79
output [7:0]  rxhfifo_wstatus;
80
output        rxhfifo_wen;
81
 
82
output [1:0]  local_fault_msg_det;
83
output [1:0]  remote_fault_msg_det;
84
 
85
output        status_crc_error_tog;
86
output        status_fragment_error_tog;
87
output        status_rxdfifo_ovflow_tog;
88
 
89
output        status_pause_frame_rx_tog;
90
 
91 23 antanguay
output        status_good_frame_rx_tog;
92
output [13:0] status_good_frame_rx_size;
93 2 antanguay
 
94
 
95
 
96 23 antanguay
 
97 2 antanguay
/*AUTOREG*/
98
// Beginning of automatic regs (for this module's undeclared outputs)
99
reg [1:0]               local_fault_msg_det;
100
reg [1:0]               remote_fault_msg_det;
101
reg [63:0]              rxdfifo_wdata;
102
reg                     rxdfifo_wen;
103
reg [7:0]               rxdfifo_wstatus;
104
reg                     rxhfifo_ren;
105
reg [63:0]              rxhfifo_wdata;
106
reg                     rxhfifo_wen;
107
reg [7:0]               rxhfifo_wstatus;
108
reg                     status_crc_error_tog;
109
reg                     status_fragment_error_tog;
110 23 antanguay
reg [13:0]              status_good_frame_rx_size;
111
reg                     status_good_frame_rx_tog;
112 2 antanguay
reg                     status_pause_frame_rx_tog;
113
reg                     status_rxdfifo_ovflow_tog;
114
// End of automatics
115
 
116
/*AUTOWIRE*/
117
 
118
 
119
reg [63:32]   xgmii_rxd_d1;
120
reg [7:4]     xgmii_rxc_d1;
121
 
122
reg [63:0]    xgxs_rxd_barrel;
123
reg [7:0]     xgxs_rxc_barrel;
124
 
125
reg [63:0]    xgxs_rxd_barrel_d1;
126
reg [7:0]     xgxs_rxc_barrel_d1;
127
 
128
reg           barrel_shift;
129
 
130
reg [31:0]    crc32_d64;
131
reg [31:0]    crc32_d8;
132
 
133
reg [3:0]     crc_bytes;
134
reg [3:0]     next_crc_bytes;
135
 
136
reg [63:0]    crc_shift_data;
137
reg           crc_start_8b;
138
reg           crc_done;
139
reg           crc_good;
140
reg           crc_clear;
141
 
142
reg [31:0]    crc_rx;
143
reg [31:0]    next_crc_rx;
144
 
145
reg [2:0]     curr_state;
146
reg [2:0]     next_state;
147
 
148
reg [13:0]    curr_byte_cnt;
149
reg [13:0]    next_byte_cnt;
150
 
151 23 antanguay
reg           frame_end_flag;
152
reg           next_frame_end_flag;
153
 
154
reg [2:0]     frame_end_bytes;
155
reg [2:0]     next_frame_end_bytes;
156
 
157 2 antanguay
reg           fragment_error;
158
reg           rxd_ovflow_error;
159
 
160
reg           coding_error;
161
reg           next_coding_error;
162
 
163
reg [7:0]     addmask;
164
reg [7:0]     datamask;
165
 
166
reg           pause_frame;
167
reg           next_pause_frame;
168
reg           pause_frame_hold;
169
 
170
reg           good_pause_frame;
171
 
172
reg           drop_data;
173
reg           next_drop_data;
174
 
175
reg           pkt_pending;
176
 
177 6 antanguay
reg           rxhfifo_ren_d1;
178
 
179 2 antanguay
reg           rxhfifo_ralmost_empty_d1;
180
 
181
 
182
parameter [2:0]
183
             SM_IDLE = 3'd0,
184
             SM_RX = 3'd1;
185
 
186 21 antanguay
// count the number of set bits in a nibble
187
function [2:0] bit_cnt4;
188
input   [3:0]   bits;
189
    begin
190
    case (bits)
191
    0:  bit_cnt4 = 0;
192
    1:  bit_cnt4 = 1;
193
    2:  bit_cnt4 = 1;
194
    3:  bit_cnt4 = 2;
195
    4:  bit_cnt4 = 1;
196
    5:  bit_cnt4 = 2;
197
    6:  bit_cnt4 = 2;
198
    7:  bit_cnt4 = 3;
199
    8:  bit_cnt4 = 1;
200
    9:  bit_cnt4 = 2;
201
    10: bit_cnt4 = 2;
202
    11: bit_cnt4 = 3;
203
    12: bit_cnt4 = 2;
204
    13: bit_cnt4 = 3;
205
    14: bit_cnt4 = 3;
206
    15: bit_cnt4 = 4;
207
    endcase
208
    end
209
endfunction
210
 
211
function [3:0] bit_cnt8;
212
input   [7:0]   bits;
213
    begin
214
    bit_cnt8 = bit_cnt4(bits[3:0]) + bit_cnt4(bits[7:4]);
215
    end
216
endfunction
217
 
218 2 antanguay
always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin
219
 
220
    if (reset_xgmii_rx_n == 1'b0) begin
221
 
222
        xgmii_rxd_d1 <= 32'b0;
223
        xgmii_rxc_d1 <= 4'b0;
224
 
225
        xgxs_rxd_barrel <= 64'b0;
226
        xgxs_rxc_barrel <= 8'b0;
227
 
228
        xgxs_rxd_barrel_d1 <= 64'b0;
229
        xgxs_rxc_barrel_d1 <= 8'b0;
230
 
231
        barrel_shift <= 1'b0;
232
 
233
        local_fault_msg_det <= 2'b0;
234
        remote_fault_msg_det <= 2'b0;
235
 
236
        crc32_d64 <= 32'b0;
237
        crc32_d8 <= 32'b0;
238
        crc_bytes <= 4'b0;
239
 
240
        crc_shift_data <= 64'b0;
241
        crc_done <= 1'b0;
242
        crc_rx <= 32'b0;
243
 
244
        pause_frame_hold <= 1'b0;
245
 
246
        status_crc_error_tog <= 1'b0;
247
        status_fragment_error_tog <= 1'b0;
248
        status_rxdfifo_ovflow_tog <= 1'b0;
249
 
250
        status_pause_frame_rx_tog <= 1'b0;
251
 
252 23 antanguay
        status_good_frame_rx_tog <= 1'b0;
253
        status_good_frame_rx_size <= 14'b0;
254
 
255 2 antanguay
    end
256
    else begin
257
 
258
        //---
259
        // Link status RC layer
260
        // Look for local/remote messages on lower 4 lanes and upper
261
        // 4 lanes. This is a 64-bit interface but look at each 32-bit
262
        // independantly.
263 21 antanguay
 
264 2 antanguay
        local_fault_msg_det[1] <= (xgmii_rxd[63:32] ==
265
                                   {`LOCAL_FAULT, 8'h0, 8'h0, `SEQUENCE} &&
266
                                   xgmii_rxc[7:4] == 4'b0001);
267
 
268
        local_fault_msg_det[0] <= (xgmii_rxd[31:0] ==
269
                                   {`LOCAL_FAULT, 8'h0, 8'h0, `SEQUENCE} &&
270
                                   xgmii_rxc[3:0] == 4'b0001);
271
 
272
        remote_fault_msg_det[1] <= (xgmii_rxd[63:32] ==
273
                                    {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE} &&
274
                                    xgmii_rxc[7:4] == 4'b0001);
275
 
276
        remote_fault_msg_det[0] <= (xgmii_rxd[31:0] ==
277
                                    {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE} &&
278
                                    xgmii_rxc[3:0] == 4'b0001);
279
 
280
 
281
        //---
282
        // Rotating barrel. This function allow us to always align the start of
283
        // a frame with LANE0. If frame starts in LANE4, it will be shifted 4 bytes
284
        // to LANE0, thus reducing the amount of logic needed at the next stage.
285
 
286
        xgmii_rxd_d1[63:32] <= xgmii_rxd[63:32];
287
        xgmii_rxc_d1[7:4] <= xgmii_rxc[7:4];
288
 
289
        if (xgmii_rxd[`LANE0] == `START && xgmii_rxc[0]) begin
290 21 antanguay
 
291 2 antanguay
            xgxs_rxd_barrel <= xgmii_rxd;
292
            xgxs_rxc_barrel <= xgmii_rxc;
293
 
294
            barrel_shift <= 1'b0;
295
 
296
        end
297
        else if (xgmii_rxd[`LANE4] == `START && xgmii_rxc[4]) begin
298
 
299
            xgxs_rxd_barrel <= {xgmii_rxd[31:0], xgmii_rxd_d1[63:32]};
300
            xgxs_rxc_barrel <= {xgmii_rxc[3:0], xgmii_rxc_d1[7:4]};
301
 
302
            barrel_shift <= 1'b1;
303
 
304
        end
305
        else if (barrel_shift) begin
306
 
307
            xgxs_rxd_barrel <= {xgmii_rxd[31:0], xgmii_rxd_d1[63:32]};
308
            xgxs_rxc_barrel <= {xgmii_rxc[3:0], xgmii_rxc_d1[7:4]};
309
 
310
        end
311
        else begin
312
 
313
            xgxs_rxd_barrel <= xgmii_rxd;
314
            xgxs_rxc_barrel <= xgmii_rxc;
315
 
316
        end
317
 
318
        xgxs_rxd_barrel_d1 <= xgxs_rxd_barrel;
319
        xgxs_rxc_barrel_d1 <= xgxs_rxc_barrel;
320
 
321
 
322
        //---
323
        // When final CRC calculation begins we capture info relevant to
324
        // current frame CRC claculation continues while next frame is
325
        // being received.
326
 
327
        if (crc_start_8b) begin
328
 
329
            pause_frame_hold <= pause_frame;
330
 
331
        end
332
 
333
        //---
334
        // CRC Checking
335
 
336
        crc_rx <= next_crc_rx;
337
 
338
        if (crc_clear) begin
339
 
340
            // CRC is cleared at the beginning of the frame, calculate
341
            // 64-bit at a time otherwise
342
 
343
            crc32_d64 <= 32'hffffffff;
344
 
345
        end
346
        else begin
347
 
348
            crc32_d64 <= nextCRC32_D64(reverse_64b(xgxs_rxd_barrel_d1), crc32_d64);
349
 
350
        end
351
 
352
        if (crc_bytes != 4'b0) begin
353
 
354
            // When reaching the end of the frame we switch from 64-bit mode
355
            // to 8-bit mode to accomodate odd number of bytes in the frame.
356
            // crc_bytes indicated the number of remaining payload byte to
357
            // compute CRC on. Calculate and decrement until it reaches 0.
358
 
359
            if (crc_bytes == 4'b1) begin
360
                crc_done <= 1'b1;
361
            end
362
 
363
            crc32_d8 <= nextCRC32_D8(reverse_8b(crc_shift_data[7:0]), crc32_d8);
364
            crc_shift_data <= {8'h00, crc_shift_data[63:8]};
365
            crc_bytes <= crc_bytes - 4'b1;
366
 
367
        end
368
        else if (crc_bytes == 4'b0) begin
369
 
370
            // Per Clause 46. Control code during data must be reported
371
            // as a CRC error. Indicated here by coding_error. Corrupt CRC
372
            // if coding error is detected.
373 21 antanguay
 
374 2 antanguay
            if (coding_error || next_coding_error) begin
375
                crc32_d8 <= ~crc32_d64;
376
            end
377
            else begin
378
                crc32_d8 <= crc32_d64;
379
            end
380
 
381
            crc_done <= 1'b0;
382
 
383
            crc_shift_data <= xgxs_rxd_barrel_d1;
384
            crc_bytes <= next_crc_bytes;
385
 
386
        end
387
 
388
        //---
389
        // Error detection
390
 
391
        if (crc_done && !crc_good) begin
392
            status_crc_error_tog <= ~status_crc_error_tog;
393
        end
394
 
395
        if (fragment_error) begin
396
            status_fragment_error_tog <= ~status_fragment_error_tog;
397
        end
398
 
399
        if (rxd_ovflow_error) begin
400
            status_rxdfifo_ovflow_tog <= ~status_rxdfifo_ovflow_tog;
401
        end
402
 
403
        //---
404
        // Frame receive indication
405
 
406
        if (good_pause_frame) begin
407
            status_pause_frame_rx_tog <= ~status_pause_frame_rx_tog;
408
        end
409
 
410 23 antanguay
        if (frame_end_flag) begin
411
            status_good_frame_rx_tog <= ~status_good_frame_rx_tog;
412
            status_good_frame_rx_size <= curr_byte_cnt + {11'b0, frame_end_bytes};
413
        end
414
 
415 2 antanguay
    end
416
 
417
end
418
 
419
 
420
always @(/*AS*/crc32_d8 or crc_done or crc_rx or pause_frame_hold) begin
421
 
422
 
423
    crc_good = 1'b0;
424
    good_pause_frame = 1'b0;
425
 
426
    if (crc_done) begin
427
 
428
        // Check CRC. If this is a pause frame, report it to cpu.
429
 
430
        if (crc_rx == ~reverse_32b(crc32_d8)) begin
431
            crc_good = 1'b1;
432
            good_pause_frame = pause_frame_hold;
433
        end
434
 
435
    end
436
 
437
end
438 21 antanguay
 
439 2 antanguay
always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin
440
 
441
    if (reset_xgmii_rx_n == 1'b0) begin
442
 
443
        curr_state <= SM_IDLE;
444
        curr_byte_cnt <= 14'b0;
445 23 antanguay
        frame_end_flag <= 1'b0;
446
        frame_end_bytes <= 3'b0;
447 2 antanguay
        coding_error <= 1'b0;
448
        pause_frame <= 1'b0;
449
 
450
    end
451
    else begin
452
 
453
        curr_state <= next_state;
454
        curr_byte_cnt <= next_byte_cnt;
455 23 antanguay
        frame_end_flag <= next_frame_end_flag;
456
        frame_end_bytes <= next_frame_end_bytes;
457 2 antanguay
        coding_error <= next_coding_error;
458
        pause_frame <= next_pause_frame;
459
 
460
    end
461
 
462
end
463
 
464
 
465
always @(/*AS*/coding_error or crc_rx or curr_byte_cnt or curr_state
466
         or pause_frame or xgxs_rxc_barrel or xgxs_rxc_barrel_d1
467
         or xgxs_rxd_barrel or xgxs_rxd_barrel_d1) begin
468
 
469
    next_state = curr_state;
470
 
471
    rxhfifo_wdata = xgxs_rxd_barrel_d1;
472 6 antanguay
    rxhfifo_wstatus = `RXSTATUS_NONE;
473 2 antanguay
    rxhfifo_wen = 1'b0;
474
 
475
    addmask[0] = !(xgxs_rxd_barrel_d1[`LANE0] == `TERMINATE && xgxs_rxc_barrel_d1[0]);
476
    addmask[1] = !(xgxs_rxd_barrel_d1[`LANE1] == `TERMINATE && xgxs_rxc_barrel_d1[1]);
477
    addmask[2] = !(xgxs_rxd_barrel_d1[`LANE2] == `TERMINATE && xgxs_rxc_barrel_d1[2]);
478
    addmask[3] = !(xgxs_rxd_barrel_d1[`LANE3] == `TERMINATE && xgxs_rxc_barrel_d1[3]);
479
    addmask[4] = !(xgxs_rxd_barrel_d1[`LANE4] == `TERMINATE && xgxs_rxc_barrel_d1[4]);
480
    addmask[5] = !(xgxs_rxd_barrel_d1[`LANE5] == `TERMINATE && xgxs_rxc_barrel_d1[5]);
481
    addmask[6] = !(xgxs_rxd_barrel_d1[`LANE6] == `TERMINATE && xgxs_rxc_barrel_d1[6]);
482
    addmask[7] = !(xgxs_rxd_barrel_d1[`LANE7] == `TERMINATE && xgxs_rxc_barrel_d1[7]);
483
 
484
    datamask[0] = addmask[0];
485
    datamask[1] = &addmask[1:0];
486
    datamask[2] = &addmask[2:0];
487
    datamask[3] = &addmask[3:0];
488
    datamask[4] = &addmask[4:0];
489
    datamask[5] = &addmask[5:0];
490
    datamask[6] = &addmask[6:0];
491
    datamask[7] = &addmask[7:0];
492
 
493
    next_crc_bytes = 4'b0;
494
    next_crc_rx = crc_rx;
495
    crc_start_8b = 1'b0;
496
    crc_clear = 1'b0;
497
 
498
    next_byte_cnt = curr_byte_cnt;
499 23 antanguay
    next_frame_end_flag = 1'b0;
500
    next_frame_end_bytes = 3'b0;
501 2 antanguay
 
502
    fragment_error = 1'b0;
503
 
504
    next_coding_error = coding_error;
505
    next_pause_frame = pause_frame;
506
 
507
    case (curr_state)
508
 
509
        SM_IDLE:
510
          begin
511
 
512
              next_byte_cnt = 14'b0;
513
              crc_clear = 1'b1;
514
              next_coding_error = 1'b0;
515
              next_pause_frame = 1'b0;
516
 
517 21 antanguay
 
518 2 antanguay
              // Detect the start of a frame
519 21 antanguay
 
520 2 antanguay
              if (xgxs_rxd_barrel_d1[`LANE0] == `START && xgxs_rxc_barrel_d1[0] &&
521
                  xgxs_rxd_barrel_d1[`LANE1] == `PREAMBLE && !xgxs_rxc_barrel_d1[1] &&
522
                  xgxs_rxd_barrel_d1[`LANE2] == `PREAMBLE && !xgxs_rxc_barrel_d1[2] &&
523
                  xgxs_rxd_barrel_d1[`LANE3] == `PREAMBLE && !xgxs_rxc_barrel_d1[3] &&
524
                  xgxs_rxd_barrel_d1[`LANE4] == `PREAMBLE && !xgxs_rxc_barrel_d1[4] &&
525
                  xgxs_rxd_barrel_d1[`LANE5] == `PREAMBLE && !xgxs_rxc_barrel_d1[5] &&
526
                  xgxs_rxd_barrel_d1[`LANE6] == `PREAMBLE && !xgxs_rxc_barrel_d1[6] &&
527
                  xgxs_rxd_barrel_d1[`LANE7] == `SFD && !xgxs_rxc_barrel_d1[7]) begin
528
 
529
                  next_state = SM_RX;
530
              end
531
 
532
          end
533
 
534
        SM_RX:
535
          begin
536
 
537
              // Pause frames are filtered
538 21 antanguay
 
539 2 antanguay
              rxhfifo_wen = !pause_frame;
540
 
541
 
542
              if (xgxs_rxd_barrel_d1[`LANE0] == `START && xgxs_rxc_barrel_d1[0] &&
543
                  xgxs_rxd_barrel_d1[`LANE7] == `SFD && !xgxs_rxc_barrel_d1[7]) begin
544
 
545
                  // Fragment received, if we are still at SOP stage don't store
546
                  // the frame. If not, write a fake EOP and flag frame as bad.
547
 
548
                  next_byte_cnt = 14'b0;
549
                  crc_clear = 1'b1;
550
                  next_coding_error = 1'b0;
551
 
552
                  fragment_error = 1'b1;
553 6 antanguay
                  rxhfifo_wstatus[`RXSTATUS_ERR] = 1'b1;
554 2 antanguay
 
555
                  if (curr_byte_cnt == 14'b0) begin
556
                      rxhfifo_wen = 1'b0;
557
                  end
558
                  else begin
559 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
560 2 antanguay
                  end
561
 
562
              end
563
              else if (curr_byte_cnt > 14'd9900) begin
564
 
565
                  // Frame too long, TERMMINATE must have been corrupted.
566
                  // Abort transfer, write a fake EOP, report as fragment.
567
 
568
                  fragment_error = 1'b1;
569 6 antanguay
                  rxhfifo_wstatus[`RXSTATUS_ERR] = 1'b1;
570 2 antanguay
 
571 6 antanguay
                  rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
572 2 antanguay
                  next_state = SM_IDLE;
573
 
574
              end
575
              else begin
576
 
577
                  // Pause frame receive, these frame will be filtered
578
 
579
                  if (curr_byte_cnt == 14'd0 &&
580
                      xgxs_rxd_barrel_d1[47:0] == `PAUSE_FRAME) begin
581
 
582
                      rxhfifo_wen = 1'b0;
583
                      next_pause_frame = 1'b1;
584
                  end
585
 
586
 
587
                  // Control character during data phase, force CRC error
588 21 antanguay
 
589 2 antanguay
                  if (|(xgxs_rxc_barrel_d1 & datamask)) begin
590
 
591
                      next_coding_error = 1'b1;
592
                  end
593
 
594
 
595
                  // Write SOP to status bits during first byte
596
 
597
                  if (curr_byte_cnt == 14'b0) begin
598 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_SOP] = 1'b1;
599 2 antanguay
                  end
600
 
601
                  /* verilator lint_off WIDTH */
602 21 antanguay
                  //next_byte_cnt = curr_byte_cnt +
603
                  //                addmask[0] + addmask[1] + addmask[2] + addmask[3] +
604
                  //                addmask[4] + addmask[5] + addmask[6] + addmask[7];
605 2 antanguay
                  /* verilator lint_on WIDTH */
606 21 antanguay
                  // don't infer a chain of adders
607 23 antanguay
                  next_byte_cnt = curr_byte_cnt + {10'b0, bit_cnt8(datamask[7:0])};
608 2 antanguay
 
609
 
610
                  // We will not write to the fifo if all is left
611
                  // are four or less bytes of crc. We also strip off the
612
                  // crc, which requires looking one cycle ahead
613 21 antanguay
                  // wstatus:
614 6 antanguay
                  //   [2:0] modulus of packet length
615 2 antanguay
 
616
                  // Look one cycle ahead for TERMINATE in lanes 0 to 4
617
 
618
                  if (xgxs_rxd_barrel[`LANE4] == `TERMINATE && xgxs_rxc_barrel[4]) begin
619 21 antanguay
 
620 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
621
                      rxhfifo_wstatus[2:0] = 3'd0;
622 2 antanguay
 
623
                      crc_start_8b = 1'b1;
624
                      next_crc_bytes = 4'd8;
625
                      next_crc_rx = xgxs_rxd_barrel[31:0];
626
 
627 23 antanguay
                      next_frame_end_flag = 1'b1;
628
                      next_frame_end_bytes = 3'd4;
629
 
630 2 antanguay
                      next_state = SM_IDLE;
631
 
632
                  end
633
 
634
                  if (xgxs_rxd_barrel[`LANE3] == `TERMINATE && xgxs_rxc_barrel[3]) begin
635
 
636 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
637
                      rxhfifo_wstatus[2:0] = 3'd7;
638 2 antanguay
 
639
                      crc_start_8b = 1'b1;
640
                      next_crc_bytes = 4'd7;
641
                      next_crc_rx = {xgxs_rxd_barrel[23:0], xgxs_rxd_barrel_d1[63:56]};
642 21 antanguay
 
643 23 antanguay
                      next_frame_end_flag = 1'b1;
644
                      next_frame_end_bytes = 3'd3;
645
 
646 2 antanguay
                      next_state = SM_IDLE;
647
 
648
                  end
649 21 antanguay
 
650 2 antanguay
                  if (xgxs_rxd_barrel[`LANE2] == `TERMINATE && xgxs_rxc_barrel[2]) begin
651
 
652 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
653
                      rxhfifo_wstatus[2:0] = 3'd6;
654 2 antanguay
 
655
                      crc_start_8b = 1'b1;
656
                      next_crc_bytes = 4'd6;
657
                      next_crc_rx = {xgxs_rxd_barrel[15:0], xgxs_rxd_barrel_d1[63:48]};
658
 
659 23 antanguay
                      next_frame_end_flag = 1'b1;
660
                      next_frame_end_bytes = 3'd2;
661
 
662 2 antanguay
                      next_state = SM_IDLE;
663
 
664
                  end
665
 
666
                  if (xgxs_rxd_barrel[`LANE1] == `TERMINATE && xgxs_rxc_barrel[1]) begin
667
 
668 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
669
                      rxhfifo_wstatus[2:0] = 3'd5;
670 2 antanguay
 
671
                      crc_start_8b = 1'b1;
672
                      next_crc_bytes = 4'd5;
673
                      next_crc_rx = {xgxs_rxd_barrel[7:0], xgxs_rxd_barrel_d1[63:40]};
674
 
675 23 antanguay
                      next_frame_end_flag = 1'b1;
676
                      next_frame_end_bytes = 3'd1;
677
 
678 2 antanguay
                      next_state = SM_IDLE;
679
 
680
                  end
681 21 antanguay
 
682 2 antanguay
                  if (xgxs_rxd_barrel[`LANE0] == `TERMINATE && xgxs_rxc_barrel[0]) begin
683
 
684 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
685
                      rxhfifo_wstatus[2:0] = 3'd4;
686 2 antanguay
 
687
                      crc_start_8b = 1'b1;
688
                      next_crc_bytes = 4'd4;
689
                      next_crc_rx = xgxs_rxd_barrel_d1[63:32];
690
 
691 23 antanguay
                      next_frame_end_flag = 1'b1;
692
 
693 2 antanguay
                      next_state = SM_IDLE;
694
 
695
                  end
696
 
697
                  // Look at current cycle for TERMINATE in lanes 5 to 7
698
 
699
                  if (xgxs_rxd_barrel_d1[`LANE7] == `TERMINATE &&
700
                      xgxs_rxc_barrel_d1[7]) begin
701
 
702 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
703
                      rxhfifo_wstatus[2:0] = 3'd3;
704 2 antanguay
 
705
                      crc_start_8b = 1'b1;
706
                      next_crc_bytes = 4'd3;
707
                      next_crc_rx = xgxs_rxd_barrel_d1[55:24];
708
 
709 23 antanguay
                      next_frame_end_flag = 1'b1;
710
 
711 2 antanguay
                      next_state = SM_IDLE;
712
 
713
                  end
714 21 antanguay
 
715 2 antanguay
                  if (xgxs_rxd_barrel_d1[`LANE6] == `TERMINATE &&
716
                      xgxs_rxc_barrel_d1[6]) begin
717
 
718 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
719
                      rxhfifo_wstatus[2:0] = 3'd2;
720 2 antanguay
 
721
                      crc_start_8b = 1'b1;
722
                      next_crc_bytes = 4'd2;
723
                      next_crc_rx = xgxs_rxd_barrel_d1[47:16];
724
 
725 23 antanguay
                      next_frame_end_flag = 1'b1;
726
 
727 2 antanguay
                      next_state = SM_IDLE;
728
 
729
                  end
730 21 antanguay
 
731 2 antanguay
                  if (xgxs_rxd_barrel_d1[`LANE5] == `TERMINATE &&
732
                      xgxs_rxc_barrel_d1[5]) begin
733
 
734 6 antanguay
                      rxhfifo_wstatus[`RXSTATUS_EOP] = 1'b1;
735
                      rxhfifo_wstatus[2:0] = 3'd1;
736 2 antanguay
 
737
                      crc_start_8b = 1'b1;
738
                      next_crc_bytes = 4'd1;
739
                      next_crc_rx = xgxs_rxd_barrel_d1[39:8];
740
 
741 23 antanguay
                      next_frame_end_flag = 1'b1;
742
 
743 2 antanguay
                      next_state = SM_IDLE;
744
 
745
                  end
746
              end
747
          end
748
 
749
        default:
750
          begin
751
              next_state = SM_IDLE;
752
          end
753
 
754
    endcase
755
 
756
end
757
 
758
 
759
always @(posedge clk_xgmii_rx or negedge reset_xgmii_rx_n) begin
760
 
761
    if (reset_xgmii_rx_n == 1'b0) begin
762
 
763
        rxhfifo_ralmost_empty_d1 <= 1'b1;
764
 
765
        drop_data <= 1'b0;
766
 
767
        pkt_pending <= 1'b0;
768
 
769 6 antanguay
        rxhfifo_ren_d1 <= 1'b0;
770
 
771 2 antanguay
    end
772
    else begin
773
 
774
        rxhfifo_ralmost_empty_d1 <= rxhfifo_ralmost_empty;
775
 
776
        drop_data <= next_drop_data;
777
 
778 6 antanguay
        pkt_pending <= rxhfifo_ren;
779 2 antanguay
 
780 6 antanguay
        rxhfifo_ren_d1 <= rxhfifo_ren;
781
 
782 2 antanguay
    end
783
 
784
end
785
 
786
always @(/*AS*/crc_done or crc_good or drop_data or pkt_pending
787
         or rxdfifo_wfull or rxhfifo_ralmost_empty_d1 or rxhfifo_rdata
788 6 antanguay
         or rxhfifo_ren_d1 or rxhfifo_rstatus) begin
789 2 antanguay
 
790
    rxd_ovflow_error = 1'b0;
791
 
792
    rxdfifo_wdata = rxhfifo_rdata;
793
    rxdfifo_wstatus = rxhfifo_rstatus;
794
 
795
    next_drop_data = drop_data;
796
 
797
 
798
    // There must be at least 8 words in holding FIFO before we start reading.
799
    // This provides enough time for CRC calculation.
800
 
801 6 antanguay
    rxhfifo_ren = !rxhfifo_ralmost_empty_d1 ||
802
                  (pkt_pending && !rxhfifo_rstatus[`RXSTATUS_EOP]);
803 2 antanguay
 
804 21 antanguay
 
805 6 antanguay
    if (rxhfifo_ren_d1 && rxhfifo_rstatus[`RXSTATUS_SOP]) begin
806 2 antanguay
 
807
        // Reset drop flag on SOP
808 21 antanguay
 
809 2 antanguay
        next_drop_data = 1'b0;
810
 
811
    end
812
 
813 6 antanguay
    if (rxhfifo_ren_d1 && rxdfifo_wfull && !next_drop_data) begin
814 2 antanguay
 
815
        // FIFO overflow, abort transfer. The rest of the frame
816
        // will be dropped. Since we can't put an EOP indication
817
        // in a fifo already full, there will be no EOP and receive
818
        // side will need to sync on next SOP.
819
 
820
        rxd_ovflow_error = 1'b1;
821
        next_drop_data = 1'b1;
822
 
823
    end
824
 
825
 
826 6 antanguay
    rxdfifo_wen = rxhfifo_ren_d1 && !next_drop_data;
827 2 antanguay
 
828
 
829
 
830
    if (crc_done && !crc_good) begin
831
 
832
        // Flag packet with error when CRC error is detected
833 21 antanguay
 
834 6 antanguay
        rxdfifo_wstatus[`RXSTATUS_ERR] = 1'b1;
835 2 antanguay
 
836
    end
837
 
838
end
839
 
840
endmodule

powered by: WebSVN 2.1.0

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