diff options
author | Martin Braun <martin.braun@ettus.com> | 2014-10-07 11:25:20 +0200 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2014-10-07 11:25:20 +0200 |
commit | fd3e84941de463fa1a7ebab0a69515b4bf2614cd (patch) | |
tree | 3fa721a13d41d2c0451d663a59a220a38fd5e614 /fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v | |
parent | 3b66804e41891e358c790b453a7a59ec7462dba4 (diff) | |
download | uhd-fd3e84941de463fa1a7ebab0a69515b4bf2614cd.tar.gz uhd-fd3e84941de463fa1a7ebab0a69515b4bf2614cd.tar.bz2 uhd-fd3e84941de463fa1a7ebab0a69515b4bf2614cd.zip |
Removed copy of FPGA source files.
Diffstat (limited to 'fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v')
-rw-r--r-- | fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v | 938 |
1 files changed, 0 insertions, 938 deletions
diff --git a/fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v b/fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v deleted file mode 100644 index 8444514ee..000000000 --- a/fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v +++ /dev/null @@ -1,938 +0,0 @@ -////////////////////////////////////////////////////////////////////// -//// //// -//// File name "tx_dequeue.v" //// -//// //// -//// This file is part of the "10GE MAC" project //// -//// http://www.opencores.org/cores/xge_mac/ //// -//// //// -//// Author(s): //// -//// - A. Tanguay (antanguay@opencores.org) //// -//// //// -////////////////////////////////////////////////////////////////////// -//// //// -//// Copyright (C) 2008 AUTHORS. All rights reserved. //// -//// //// -//// This source file may be used and distributed without //// -//// restriction provided that this copyright statement is not //// -//// removed from the file and that any derivative work contains //// -//// the original copyright notice and the associated disclaimer. //// -//// //// -//// This source file is free software; you can redistribute it //// -//// and/or modify it under the terms of the GNU Lesser General //// -//// Public License as published by the Free Software Foundation; //// -//// either version 2.1 of the License, or (at your option) any //// -//// later version. //// -//// //// -//// This source is distributed in the hope that it will be //// -//// useful, but WITHOUT ANY WARRANTY; without even the implied //// -//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// -//// PURPOSE. See the GNU Lesser General Public License for more //// -//// details. //// -//// //// -//// You should have received a copy of the GNU Lesser General //// -//// Public License along with this source; if not, download it //// -//// from http://www.opencores.org/lgpl.shtml //// -//// //// -////////////////////////////////////////////////////////////////////// - - -`include "defines.v" - -module tx_dequeue(/*AUTOARG*/ - // Outputs - txdfifo_ren, txhfifo_ren, txhfifo_wdata, txhfifo_wstatus, - txhfifo_wen, xgmii_txd, xgmii_txc, status_txdfifo_udflow_tog, - // Inputs - clk_xgmii_tx, reset_xgmii_tx_n, ctrl_tx_enable_ctx, - status_local_fault_ctx, status_remote_fault_ctx, txdfifo_rdata, - txdfifo_rstatus, txdfifo_rempty, txdfifo_ralmost_empty, - txhfifo_rdata, txhfifo_rstatus, txhfifo_rempty, - txhfifo_ralmost_empty, txhfifo_wfull, txhfifo_walmost_full - ); -`include "CRC32_D64.v" -`include "CRC32_D8.v" -`include "utils.v" - -input clk_xgmii_tx; -input reset_xgmii_tx_n; - -input ctrl_tx_enable_ctx; - -input status_local_fault_ctx; -input status_remote_fault_ctx; - -input [63:0] txdfifo_rdata; -input [7:0] txdfifo_rstatus; -input txdfifo_rempty; -input txdfifo_ralmost_empty; - -input [63:0] txhfifo_rdata; -input [7:0] txhfifo_rstatus; -input txhfifo_rempty; -input txhfifo_ralmost_empty; - -input txhfifo_wfull; -input txhfifo_walmost_full; - -output txdfifo_ren; - -output txhfifo_ren; - -output [63:0] txhfifo_wdata; -output [7:0] txhfifo_wstatus; -output txhfifo_wen; - -output [63:0] xgmii_txd; -output [7:0] xgmii_txc; - -output status_txdfifo_udflow_tog; - - - - -/*AUTOREG*/ -// Beginning of automatic regs (for this module's undeclared outputs) -reg status_txdfifo_udflow_tog; -reg txdfifo_ren; -reg txhfifo_ren; -reg [63:0] txhfifo_wdata; -reg txhfifo_wen; -reg [7:0] txhfifo_wstatus; -reg [7:0] xgmii_txc; -reg [63:0] xgmii_txd; -// End of automatics - -/*AUTOWIRE*/ - - -reg [63:0] xgxs_txd; -reg [7:0] xgxs_txc; - -reg [63:0] next_xgxs_txd; -reg [7:0] next_xgxs_txc; - -reg [2:0] curr_state_enc; -reg [2:0] next_state_enc; - -reg [0:0] curr_state_pad; -reg [0:0] next_state_pad; - -reg start_on_lane0; -reg next_start_on_lane0; - -reg [2:0] ifg_deficit; -reg [2:0] next_ifg_deficit; - -reg ifg_4b_add; -reg next_ifg_4b_add; - -reg ifg_8b_add; -reg next_ifg_8b_add; - -reg ifg_8b2_add; -reg next_ifg_8b2_add; - -reg [7:0] eop; -reg [7:0] next_eop; - -reg [63:32] xgxs_txd_barrel; -reg [7:4] xgxs_txc_barrel; - -reg [63:0] txhfifo_rdata_d1; - -reg [13:0] byte_cnt; - -reg [31:0] crc32_d64; -reg [31:0] crc32_d8; -reg [31:0] crc32_tx; - -reg [63:0] shift_crc_data; -reg [3:0] shift_crc_eop; -reg [3:0] shift_crc_cnt; - -reg [31:0] crc_data; - -reg frame_available; -reg next_frame_available; - -reg [63:0] next_txhfifo_wdata; -reg [7:0] next_txhfifo_wstatus; -reg next_txhfifo_wen; - -reg txdfifo_ren_d1; - -parameter [2:0] - SM_IDLE = 3'd0, - SM_PREAMBLE = 3'd1, - SM_TX = 3'd2, - SM_EOP = 3'd3, - SM_TERM = 3'd4, - SM_TERM_FAIL = 3'd5, - SM_IFG = 3'd6; - -parameter [0:0] - SM_PAD_EQ = 1'd0, - SM_PAD_PAD = 1'd1; - - -//--- -// RC layer - -always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin - - if (reset_xgmii_tx_n == 1'b0) begin - - xgmii_txd <= {8{`IDLE}}; - xgmii_txc <= 8'hff; - - end - else begin - - - //--- - // RC Layer, insert local or remote fault messages based on status - // of fault state-machine - - if (status_local_fault_ctx) begin - - // If local fault detected, send remote fault message to - // link partner - - xgmii_txd <= {`REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE, - `REMOTE_FAULT, 8'h0, 8'h0, `SEQUENCE}; - xgmii_txc <= {4'b0001, 4'b0001}; - end - else if (status_remote_fault_ctx) begin - - // If remote fault detected, inhibit transmission and send - // idle codes - - xgmii_txd <= {8{`IDLE}}; - xgmii_txc <= 8'hff; - end - else begin - xgmii_txd <= xgxs_txd; - xgmii_txc <= xgxs_txc; - end - end - -end - - -always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin - - if (reset_xgmii_tx_n == 1'b0) begin - - curr_state_enc <= SM_IDLE; - - start_on_lane0 <= 1'b1; - ifg_deficit <= 3'b0; - ifg_4b_add <= 1'b0; - ifg_8b_add <= 1'b0; - ifg_8b2_add <= 1'b0; - - eop <= 8'b0; - - txhfifo_rdata_d1 <= 64'b0; - - xgxs_txd_barrel <= {4{`IDLE}}; - xgxs_txc_barrel <= 4'hf; - - frame_available <= 1'b0; - - xgxs_txd <= {8{`IDLE}}; - xgxs_txc <= 8'hff; - - status_txdfifo_udflow_tog <= 1'b0; - - end - else begin - - curr_state_enc <= next_state_enc; - - start_on_lane0 <= next_start_on_lane0; - ifg_deficit <= next_ifg_deficit; - ifg_4b_add <= next_ifg_4b_add; - ifg_8b_add <= next_ifg_8b_add; - ifg_8b2_add <= next_ifg_8b2_add; - - eop <= next_eop; - - txhfifo_rdata_d1 <= txhfifo_rdata; - - xgxs_txd_barrel <= next_xgxs_txd[63:32]; - xgxs_txc_barrel <= next_xgxs_txc[7:4]; - - frame_available <= next_frame_available; - - //--- - // Barrel shifter. Previous stage always align packet with LANE0. - // This stage allow us to shift packet to align with LANE4 if needed - // for correct inter frame gap (IFG). - - if (next_start_on_lane0) begin - - xgxs_txd <= next_xgxs_txd; - xgxs_txc <= next_xgxs_txc; - - end - else begin - - xgxs_txd <= {next_xgxs_txd[31:0], xgxs_txd_barrel}; - xgxs_txc <= {next_xgxs_txc[3:0], xgxs_txc_barrel}; - - end - - //--- - // FIFO errors, used to generate interrupts. - - if (txdfifo_ren && txdfifo_rempty) begin - status_txdfifo_udflow_tog <= ~status_txdfifo_udflow_tog; - end - - end - -end - -always @(/*AS*/crc32_tx or ctrl_tx_enable_ctx or curr_state_enc or eop - or frame_available or ifg_4b_add or ifg_8b2_add or ifg_8b_add - or ifg_deficit or start_on_lane0 or status_local_fault_ctx - or txhfifo_ralmost_empty or txhfifo_rdata_d1 - or txhfifo_rempty or txhfifo_rstatus) begin - - next_state_enc = curr_state_enc; - - next_start_on_lane0 = start_on_lane0; - next_ifg_deficit = ifg_deficit; - next_ifg_4b_add = ifg_4b_add; - next_ifg_8b_add = ifg_8b_add; - next_ifg_8b2_add = ifg_8b2_add; - - next_eop = eop; - - next_xgxs_txd = {8{`IDLE}}; - next_xgxs_txc = 8'hff; - - txhfifo_ren = 1'b0; - - next_frame_available = frame_available; - - case (curr_state_enc) - - SM_IDLE: - begin - - // Wait for frame to be available. There should be a least N bytes in the - // data fifo or a crc in the control fifo. The N bytes in the data fifo - // give time to the enqueue engine to calculate crc and write it to the - // control fifo. If crc is already in control fifo we can start transmitting - // with no concern. Transmission is inhibited if local or remote faults - // are detected. - - if (ctrl_tx_enable_ctx && frame_available && - !status_local_fault_ctx && !status_local_fault_ctx) begin - - txhfifo_ren = 1'b1; - next_state_enc = SM_PREAMBLE; - - end - else begin - - next_frame_available = !txhfifo_ralmost_empty; - next_ifg_4b_add = 1'b0; - - end - - end - - SM_PREAMBLE: - begin - - // On reading SOP from fifo, send SFD and preamble characters - - if (txhfifo_rstatus[`TXSTATUS_SOP]) begin - - next_xgxs_txd = {`SFD, {6{`PREAMBLE}}, `START}; - next_xgxs_txc = 8'h01; - - txhfifo_ren = 1'b1; - - next_state_enc = SM_TX; - - end - else begin - - next_frame_available = 1'b0; - next_state_enc = SM_IDLE; - - end - - - // Depending on deficit idle count calculations, add 4 bytes - // or IFG or not. This will determine on which lane start the - // next frame. - - if (ifg_4b_add) begin - next_start_on_lane0 = 1'b0; - end - else begin - next_start_on_lane0 = 1'b1; - end - - end - - SM_TX: - begin - - next_xgxs_txd = txhfifo_rdata_d1; - next_xgxs_txc = 8'h00; - - txhfifo_ren = 1'b1; - - - // Wait for EOP indication to be read from the fifo, then - // transition to next state. - - if (txhfifo_rstatus[`TXSTATUS_EOP]) begin - - txhfifo_ren = 1'b0; - next_frame_available = !txhfifo_ralmost_empty; - next_state_enc = SM_EOP; - - end - else if (txhfifo_rempty || txhfifo_rstatus[`TXSTATUS_SOP]) begin - - // Failure condition, we did not see EOP and there - // is no more data in fifo or SOP, force end of packet transmit. - - next_state_enc = SM_TERM_FAIL; - - end - - next_eop[0] = txhfifo_rstatus[2:0] == 3'd1; - next_eop[1] = txhfifo_rstatus[2:0] == 3'd2; - next_eop[2] = txhfifo_rstatus[2:0] == 3'd3; - next_eop[3] = txhfifo_rstatus[2:0] == 3'd4; - next_eop[4] = txhfifo_rstatus[2:0] == 3'd5; - next_eop[5] = txhfifo_rstatus[2:0] == 3'd6; - next_eop[6] = txhfifo_rstatus[2:0] == 3'd7; - next_eop[7] = txhfifo_rstatus[2:0] == 3'd0; - - end - - SM_EOP: - begin - - // Insert TERMINATE character in correct lane depending on position - // of EOP read from fifo. Also insert CRC read from control fifo. - - if (eop[0]) begin - next_xgxs_txd = {{2{`IDLE}}, `TERMINATE, - crc32_tx[31:0], txhfifo_rdata_d1[7:0]}; - next_xgxs_txc = 8'b11100000; - end - - if (eop[1]) begin - next_xgxs_txd = {`IDLE, `TERMINATE, - crc32_tx[31:0], txhfifo_rdata_d1[15:0]}; - next_xgxs_txc = 8'b11000000; - end - - if (eop[2]) begin - next_xgxs_txd = {`TERMINATE, crc32_tx[31:0], txhfifo_rdata_d1[23:0]}; - next_xgxs_txc = 8'b10000000; - end - - if (eop[3]) begin - next_xgxs_txd = {crc32_tx[31:0], txhfifo_rdata_d1[31:0]}; - next_xgxs_txc = 8'b00000000; - end - - if (eop[4]) begin - next_xgxs_txd = {crc32_tx[23:0], txhfifo_rdata_d1[39:0]}; - next_xgxs_txc = 8'b00000000; - end - - if (eop[5]) begin - next_xgxs_txd = {crc32_tx[15:0], txhfifo_rdata_d1[47:0]}; - next_xgxs_txc = 8'b00000000; - end - - if (eop[6]) begin - next_xgxs_txd = {crc32_tx[7:0], txhfifo_rdata_d1[55:0]}; - next_xgxs_txc = 8'b00000000; - end - - if (eop[7]) begin - next_xgxs_txd = {txhfifo_rdata_d1[63:0]}; - next_xgxs_txc = 8'b00000000; - end - - if (!frame_available) begin - - // If there is not another frame ready to be transmitted, interface - // will go idle and idle deficit idle count calculation is irrelevant. - // Set deficit to 0. - - next_ifg_deficit = 3'b0; - - end - else begin - - // Idle deficit count calculated based on number of "wasted" bytes - // between TERMINATE and alignment of next frame in LANE0. - - next_ifg_deficit = ifg_deficit + - {2'b0, eop[0] | eop[4]} + - {1'b0, eop[1] | eop[5], 1'b0} + - {1'b0, eop[2] | eop[6], - eop[2] | eop[6]}; - end - - // IFG corrections based on deficit count and previous starting lane - // Calculated based on following table: - // - // DIC=0 DIC=1 DIC=2 DIC=3 - // ------------- ------------- ------------- ------------- - // PktLen IFG Next IFG Next IFG Next IFG Next - // Modulus Length DIC Length DIC Length DIC Length DIC - // ----------------------------------------------------------------------- - // 0 12 0 12 1 12 2 12 3 - // 1 11 1 11 2 11 3 15 0 - // 2 10 2 10 3 14 0 14 1 - // 3 9 3 13 0 13 1 13 2 - // - // - // In logic it translates into adding 4, 8, or 12 bytes of IFG relative - // to LANE0. - // IFG and Add columns assume no deficit applied - // IFG+DIC and Add+DIC assume deficit must be applied - // - // Start lane 0 Start lane 4 - // EOP Pads IFG IFG+DIC Add Add+DIC Add Add IFG - // 0 3 11 15 8 12 12 16 - // 1 2 10 14 8 12 12 16 - // 2 1 9 13 8 12 12 16 - // 3 8 12 12 4 4 8 8 - // 4 7 11 15 4 8 8 12 - // 5 6 10 14 4 8 8 12 - // 6 5 9 13 4 8 8 12 - // 7 4 12 12 8 8 12 12 - - if (!frame_available) begin - - // If there is not another frame ready to be transmitted, interface - // will go idle and idle deficit idle count calculation is irrelevant. - - next_ifg_4b_add = 1'b0; - next_ifg_8b_add = 1'b0; - next_ifg_8b2_add = 1'b0; - - end - else if (next_ifg_deficit[2] == ifg_deficit[2]) begin - - // Add 4 bytes IFG - - next_ifg_4b_add = (eop[0] & !start_on_lane0) | - (eop[1] & !start_on_lane0) | - (eop[2] & !start_on_lane0) | - (eop[3] & start_on_lane0) | - (eop[4] & start_on_lane0) | - (eop[5] & start_on_lane0) | - (eop[6] & start_on_lane0) | - (eop[7] & !start_on_lane0); - - // Add 8 bytes IFG - - next_ifg_8b_add = (eop[0]) | - (eop[1]) | - (eop[2]) | - (eop[3] & !start_on_lane0) | - (eop[4] & !start_on_lane0) | - (eop[5] & !start_on_lane0) | - (eop[6] & !start_on_lane0) | - (eop[7]); - - // Add another 8 bytes IFG - - next_ifg_8b2_add = 1'b0; - - end - else begin - - // Add 4 bytes IFG - - next_ifg_4b_add = (eop[0] & start_on_lane0) | - (eop[1] & start_on_lane0) | - (eop[2] & start_on_lane0) | - (eop[3] & start_on_lane0) | - (eop[4] & !start_on_lane0) | - (eop[5] & !start_on_lane0) | - (eop[6] & !start_on_lane0) | - (eop[7] & !start_on_lane0); - - // Add 8 bytes IFG - - next_ifg_8b_add = (eop[0]) | - (eop[1]) | - (eop[2]) | - (eop[3] & !start_on_lane0) | - (eop[4]) | - (eop[5]) | - (eop[6]) | - (eop[7]); - - // Add another 8 bytes IFG - - next_ifg_8b2_add = (eop[0] & !start_on_lane0) | - (eop[1] & !start_on_lane0) | - (eop[2] & !start_on_lane0); - - end - - if (|eop[2:0]) begin - - if (frame_available) begin - - // Next state depends on number of IFG bytes to be inserted. - // Skip idle state if needed. - - if (next_ifg_8b2_add) begin - next_state_enc = SM_IFG; - end - else if (next_ifg_8b_add) begin - next_state_enc = SM_IDLE; - end - else begin - txhfifo_ren = 1'b1; - next_state_enc = SM_PREAMBLE; - end - - end - else begin - next_state_enc = SM_IFG; - end - end - - if (|eop[7:3]) begin - next_state_enc = SM_TERM; - end - - end - - SM_TERM: - begin - - // Insert TERMINATE character in correct lane depending on position - // of EOP read from fifo. Also insert CRC read from control fifo. - - if (eop[3]) begin - next_xgxs_txd = {{7{`IDLE}}, `TERMINATE}; - next_xgxs_txc = 8'b11111111; - end - - if (eop[4]) begin - next_xgxs_txd = {{6{`IDLE}}, `TERMINATE, crc32_tx[31:24]}; - next_xgxs_txc = 8'b11111110; - end - - if (eop[5]) begin - next_xgxs_txd = {{5{`IDLE}}, `TERMINATE, crc32_tx[31:16]}; - next_xgxs_txc = 8'b11111100; - end - - if (eop[6]) begin - next_xgxs_txd = {{4{`IDLE}}, `TERMINATE, crc32_tx[31:8]}; - next_xgxs_txc = 8'b11111000; - end - - if (eop[7]) begin - next_xgxs_txd = {{3{`IDLE}}, `TERMINATE, crc32_tx[31:0]}; - next_xgxs_txc = 8'b11110000; - end - - // Next state depends on number of IFG bytes to be inserted. - // Skip idle state if needed. - - if (frame_available && !ifg_8b_add) begin - txhfifo_ren = 1'b1; - next_state_enc = SM_PREAMBLE; - end - else if (frame_available) begin - next_state_enc = SM_IDLE; - end - else begin - next_state_enc = SM_IFG; - end - - end - - SM_TERM_FAIL: - begin - - next_xgxs_txd = {{7{`IDLE}}, `TERMINATE}; - next_xgxs_txc = 8'b11111111; - next_state_enc = SM_IFG; - - end - - SM_IFG: - begin - - next_state_enc = SM_IDLE; - - end - - default: - begin - next_state_enc = SM_IDLE; - end - - endcase - -end - - -always @(/*AS*/crc32_d64 or txhfifo_wen or txhfifo_wstatus) begin - - if (txhfifo_wen && txhfifo_wstatus[`TXSTATUS_SOP]) begin - crc_data = 32'hffffffff; - end - else begin - crc_data = crc32_d64; - end - -end - -always @(/*AS*/byte_cnt or curr_state_pad or txdfifo_rdata - or txdfifo_rempty or txdfifo_ren_d1 or txdfifo_rstatus - or txhfifo_walmost_full) begin - - next_state_pad = curr_state_pad; - - next_txhfifo_wdata = txdfifo_rdata; - next_txhfifo_wstatus = txdfifo_rstatus; - - txdfifo_ren = 1'b0; - next_txhfifo_wen = 1'b0; - - case (curr_state_pad) - - SM_PAD_EQ: begin - - - //--- - // If room availabe in hoding fifo and data available in - // data fifo, transfer data words. If transmit state machine - // is reading from fifo we can assume room will be available. - - if (!txhfifo_walmost_full) begin - - txdfifo_ren = !txdfifo_rempty; - - end - - - //--- - // This logic dependent on read during previous cycle. - - if (txdfifo_ren_d1) begin - - next_txhfifo_wen = 1'b1; - - // On EOP, decide if padding is required for this packet. - - if (txdfifo_rstatus[`TXSTATUS_EOP]) begin - - if (byte_cnt < 14'd56) begin - - next_txhfifo_wstatus = `TXSTATUS_NONE; - txdfifo_ren = 1'b0; - next_state_pad = SM_PAD_PAD; - - end - else if (byte_cnt == 14'd56 && - (txdfifo_rstatus[2:0] == 3'd1 || - txdfifo_rstatus[2:0] == 3'd2 || - txdfifo_rstatus[2:0] == 3'd3)) begin - - // Pad up to LANE3, keep the other 4 bytes for crc that will - // be inserted by dequeue engine. - - next_txhfifo_wstatus[2:0] = 3'd4; - - // Pad end bytes with zeros. - - if (txdfifo_rstatus[2:0] == 3'd1) - next_txhfifo_wdata[31:8] = 24'b0; - if (txdfifo_rstatus[2:0] == 3'd2) - next_txhfifo_wdata[31:16] = 16'b0; - if (txdfifo_rstatus[2:0] == 3'd3) - next_txhfifo_wdata[31:24] = 8'b0; - - txdfifo_ren = 1'b0; - - end - else begin - - txdfifo_ren = 1'b0; - - end - - end - - end - - end - - SM_PAD_PAD: begin - - //--- - // Pad packet to 64 bytes by writting zeros to holding fifo. - - if (!txhfifo_walmost_full) begin - - next_txhfifo_wdata = 64'b0; - next_txhfifo_wstatus = `TXSTATUS_NONE; - next_txhfifo_wen = 1'b1; - - if (byte_cnt == 14'd56) begin - - - // Pad up to LANE3, keep the other 4 bytes for crc that will - // be inserted by dequeue engine. - - next_txhfifo_wstatus[`TXSTATUS_EOP] = 1'b1; - next_txhfifo_wstatus[2:0] = 3'd4; - - next_state_pad = SM_PAD_EQ; - - end - - end - - end - - default: - begin - next_state_pad = SM_PAD_EQ; - end - - endcase - -end - - -always @(posedge clk_xgmii_tx or negedge reset_xgmii_tx_n) begin - - if (reset_xgmii_tx_n == 1'b0) begin - - curr_state_pad <= SM_PAD_EQ; - - txdfifo_ren_d1 <= 1'b0; - - txhfifo_wdata <= 64'b0; - txhfifo_wstatus <= 8'b0; - txhfifo_wen <= 1'b0; - - byte_cnt <= 14'b0; - - shift_crc_data <= 64'b0; - shift_crc_eop <= 4'b0; - shift_crc_cnt <= 4'b0; - - end - else begin - - curr_state_pad <= next_state_pad; - - txdfifo_ren_d1 <= txdfifo_ren; - - txhfifo_wdata <= next_txhfifo_wdata; - txhfifo_wstatus <= next_txhfifo_wstatus; - txhfifo_wen <= next_txhfifo_wen; - - - //--- - // Reset byte count on SOP - - if (next_txhfifo_wen) begin - - if (next_txhfifo_wstatus[`TXSTATUS_SOP]) begin - - byte_cnt <= 14'd8; - - end - else begin - - byte_cnt <= byte_cnt + 14'd8; - - end - - end - - - //--- - // Calculate CRC as data is written to holding fifo. The holding fifo creates - // a delay that allow the CRC calculation to complete before the end of the frame - // is ready to be transmited. - - if (txhfifo_wen) begin - - crc32_d64 <= nextCRC32_D64(reverse_64b(txhfifo_wdata), crc_data); - - end - - if (txhfifo_wen && txhfifo_wstatus[`TXSTATUS_EOP]) begin - - // Last bytes calculated 8-bit at a time instead of 64-bit. Start - // this process at the end of the frame. - - crc32_d8 <= crc32_d64; - - shift_crc_data <= txhfifo_wdata; - shift_crc_cnt <= 4'd9; - - if (txhfifo_wstatus[2:0] == 3'b0) begin - shift_crc_eop <= 4'd8; - end - else begin - shift_crc_eop <= {1'b0, txhfifo_wstatus[2:0]}; - end - - end - else if (shift_crc_eop != 4'b0) begin - - // Complete crc calculation 8-bit at a time until finished. This can - // be 1 to 8 bytes long. - - crc32_d8 <= nextCRC32_D8(reverse_8b(shift_crc_data[7:0]), crc32_d8); - - shift_crc_data <= {8'b0, shift_crc_data[63:8]}; - shift_crc_eop <= shift_crc_eop - 4'd1; - - end - - - //--- - // Update CRC register at the end of calculation. Always update after 8 - // cycles for deterministic results, even if a single byte was present in - // last data word. - - if (shift_crc_cnt == 4'b1) begin - - crc32_tx <= ~reverse_32b(crc32_d8); - - end - else begin - - shift_crc_cnt <= shift_crc_cnt - 4'd1; - - end - - end - -end - -endmodule - |