aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v
diff options
context:
space:
mode:
authorMartin Braun <martin.braun@ettus.com>2014-10-07 11:25:20 +0200
committerMartin Braun <martin.braun@ettus.com>2014-10-07 11:25:20 +0200
commitfd3e84941de463fa1a7ebab0a69515b4bf2614cd (patch)
tree3fa721a13d41d2c0451d663a59a220a38fd5e614 /fpga/usrp3/lib/xge/rtl/verilog/tx_dequeue.v
parent3b66804e41891e358c790b453a7a59ec7462dba4 (diff)
downloaduhd-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.v938
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
-