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 27

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

powered by: WebSVN 2.1.0

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