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 28

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

powered by: WebSVN 2.1.0

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