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 21

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

powered by: WebSVN 2.1.0

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