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