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 11

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

powered by: WebSVN 2.1.0

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