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