summaryrefslogtreecommitdiffhomepage
path: root/src/switch.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/switch.v')
-rw-r--r--src/switch.v656
1 files changed, 335 insertions, 321 deletions
diff --git a/src/switch.v b/src/switch.v
index fa6d75e..661d848 100644
--- a/src/switch.v
+++ b/src/switch.v
@@ -38,18 +38,21 @@ module switch #(parameter NUM_PHYS=3)
input [8:0] rx_d_20,
input [8:0] rx_d_21,
input [8:0] rx_d_u0,
+ input [8:0] rx_mle_fifo_d,
// RX FIFO read enables
output reg rx_fifo_re_01, rx_fifo_re_02, rx_fifo_re_0u,
output reg rx_fifo_re_10, rx_fifo_re_12,
output reg rx_fifo_re_20, rx_fifo_re_21,
output reg rx_fifo_re_u0,
+ output reg rx_fifo_re_mle,
// RX FIFO Empty flags
input rx_fifo_empty_01, rx_fifo_empty_02, rx_fifo_empty_0u,
input rx_fifo_empty_10, rx_fifo_empty_12,
input rx_fifo_empty_20, rx_fifo_empty_21,
input rx_fifo_empty_u0,
+ input rx_fifo_empty_mle,
input [NUM_PHYS-1:0] rx_wr_done,
@@ -58,6 +61,7 @@ module switch #(parameter NUM_PHYS=3)
input [10:0] rx1_byte_cnt,
input [10:0] rx2_byte_cnt,
input [10:0] rxu_byte_cnt,
+ input [10:0] rx_mle_byte_cnt,
// TX FIFO output from internal muxes
output reg [8:0] tx_d0,
@@ -94,348 +98,358 @@ module switch #(parameter NUM_PHYS=3)
input tx_custom
);
-
-
-// IPG for Port 0
-wire ipg_met;
-reg [6:0] ipg_cnt;
-
-reg rx_fifo_empty_u0_m1, rx_fifo_empty_u0_m2;
-
-
-reg [3:0] fr_100mbit_cnt;
-reg i_tx_fifo_we_u;
-reg [10:0] i_rx0_byte_cnt, i_rx1_byte_cnt, i_rx2_byte_cnt;
-
-`define INCLUDED
-`include "ethernet_params.v"
-`undef INCLUDED
-
-localparam SEL_PHY0 = 3'b000,
- SEL_PHY1 = 3'b001,
- SEL_PHY2 = 3'b010,
- SEL_UC = 3'b111;
-
-
-// capture the rx_byte_cnt values when write is done. TODO: needs to be a shallow Q to match FIFO
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- i_rx0_byte_cnt <= 'h0;
- else if ( rx_wr_done[0])
- i_rx0_byte_cnt <= rx0_byte_cnt;
-
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- i_rx1_byte_cnt <= 'h0;
- else if ( rx_wr_done[1])
- i_rx1_byte_cnt <= rx1_byte_cnt;
-
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- i_rx2_byte_cnt <= 'h0;
- else if ( rx_wr_done[2])
- i_rx2_byte_cnt <= rx2_byte_cnt;
-
-assign ipg_met = ipg_cnt >= IPG ? 1'b1 : 1'b0;
-
-/* free running 100Mbit counter */
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- fr_100mbit_cnt <= 4'd0;
- else if ( fr_100mbit_cnt == 4'd9 )
- fr_100mbit_cnt <= 4'd0;
- else
- fr_100mbit_cnt <= fr_100mbit_cnt + 1'b1;
-
-/* IPG counter */
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- ipg_cnt <= 7'd0;
- else if ( tx_f[0] && tx_mode0 >= TX_MODE_XMT_PKT )
- ipg_cnt <= 7'd0;
- else if ( mode_100Mbit[0] && fr_100mbit_cnt == 4'd9 && !ipg_met )
- ipg_cnt <= ipg_cnt + 1;
- else if ( !mode_100Mbit[0] && !ipg_met )
- ipg_cnt <= ipg_cnt + 1'b1;
-
-
-// Transfer to the pclk domain
-always @(posedge clk, negedge rstn)
- if ( !rstn ) begin
- rx_fifo_empty_u0_m1 <= 1'b1;
- rx_fifo_empty_u0_m2 <= 1'b1;
- end
- else begin
- rx_fifo_empty_u0_m1 <= rx_fifo_empty_u0;
- rx_fifo_empty_u0_m2 <= rx_fifo_empty_u0_m1;
- end
-
-
-// TX0 Switch Logic
-// Possible sources: u, 1, 2
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- begin
- tx_mode0 <= TX_MODE_AN;
- tx0_src_sel <= SEL_PHY1;
- tx0_byte_cnt <= 'h0;
- end
- else if ( tx_f[0] )
- case( tx_mode0 )
- TX_MODE_AN:
- if ( phy_up[0] )
- tx_mode0 <= TX_MODE_IDLE;
- TX_MODE_IDLE:
- if ( !phy_up[0] )
- tx_mode0 <= TX_MODE_AN;
- else if ( !ipg_met )
- tx_mode0 <= TX_MODE_IDLE;
- else if (!rx_fifo_empty_u0_m2 ) // controller has data
- begin
- tx_mode0 <= TX_MODE_XMT_CUSTOM;
- tx0_src_sel <= SEL_UC;
- tx0_byte_cnt <= rxu_byte_cnt;
- end
-`ifdef PHY2_PRESENT
- else if (tx0_src_sel==SEL_PHY1 && !rx_fifo_empty_20 )
- begin
- tx_mode0 <= TX_MODE_XMT_PKT;
- tx0_src_sel <= SEL_PHY2;
- tx0_byte_cnt <= i_rx2_byte_cnt;
- end
-`endif
- else if (!rx_fifo_empty_10 )
- begin
- tx_mode0 <= TX_MODE_XMT_PKT;
- tx0_src_sel <= SEL_PHY1;
- tx0_byte_cnt <= i_rx1_byte_cnt;
- end
-`ifdef PHY2_PRESENT
- else if (!rx_fifo_empty_20 )
- begin
- tx_mode0 <= TX_MODE_XMT_PKT;
- tx0_src_sel <= SEL_PHY2;
- tx0_byte_cnt <= i_rx2_byte_cnt;
- end
-`endif
- TX_MODE_XMT_PKT:
- if ( !phy_up[0] )
- tx_mode0 <= TX_MODE_AN;
- else
- tx_mode0 <= TX_MODE_IDLE;
- default: tx_mode0 <= TX_MODE_IDLE;
- endcase
+ `define INCLUDED
+ `include "ethernet_params.v"
+ `undef INCLUDED
+ // IPG for Port 0
+ wire ipg_met;
+ reg [6:0] ipg_cnt;
+
+ reg rx_fifo_empty_u0_m1, rx_fifo_empty_u0_m2;
+
+
+ reg [3:0] fr_100mbit_cnt;
+ reg i_tx_fifo_we_u;
+ reg [10:0] i_rx0_byte_cnt, i_rx1_byte_cnt, i_rx2_byte_cnt;
-// TX0 data mux
-always @(*) begin
- case(tx0_src_sel)
- SEL_PHY0: tx_d0 = 9'h000;
- SEL_PHY1: tx_d0 = rx_d_10;
- SEL_PHY2: tx_d0 = rx_d_20;
- SEL_UC: tx_d0 = rx_d_u0;
- default: tx_d0 = 9'h000;
- endcase
-end
-
-// TX0 FIFO read enable
-always @(*) begin
- rx_fifo_re_10 = 1'b0;
- rx_fifo_re_20 = 1'b0;
- rx_fifo_re_u0 = 1'b0;
- case(tx0_src_sel)
- SEL_PHY1: rx_fifo_re_10 = tx_fifo_re[0];
- SEL_PHY2: rx_fifo_re_20 = tx_fifo_re[0];
- SEL_UC: rx_fifo_re_u0 = tx_fifo_re[0];
- endcase
-end
-
-// TX0 FIFO Empty Routing
-always @(*) begin
- case(tx0_src_sel)
- SEL_PHY1: tx_fifo_empty[0] = rx_fifo_empty_10;
- SEL_PHY2: tx_fifo_empty[0] = rx_fifo_empty_20;
- SEL_UC: tx_fifo_empty[0] = rx_fifo_empty_u0_m2;
- default: tx_fifo_empty[0] = 1'b1;
- endcase
-end
-// TX1 Switch Logic
-// Possible sources: 0, 2 in priority
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- begin
- tx_mode1 <= TX_MODE_AN;
- tx1_src_sel <= SEL_PHY0;
- end
- else if ( tx_f[1] )
- case( tx_mode1 )
- TX_MODE_AN:
- if ( phy_up[1] )
- tx_mode1 <= TX_MODE_IDLE;
- TX_MODE_IDLE:
- if ( !phy_up[1] )
- tx_mode1 <= TX_MODE_AN;
-`ifdef PHY2_PRESENT
- else if (tx1_src_sel==SEL_PHY0 && !rx_fifo_empty_21 )
- begin
- tx_mode1 <= TX_MODE_XMT_PKT;
- tx1_src_sel <= SEL_PHY2;
- end
-`endif
- else if (!rx_fifo_empty_01 )
- begin
- tx_mode1 <= TX_MODE_XMT_PKT;
- tx1_src_sel <= SEL_PHY0;
- end
-`ifdef PHY2_PRESENT
- else if (!rx_fifo_empty_21 )
- begin
- tx_mode1 <= TX_MODE_XMT_PKT;
- tx1_src_sel <= SEL_PHY2;
- end
-`endif
- TX_MODE_XMT_PKT:
- if ( !phy_up[1] )
- tx_mode1 <= TX_MODE_AN;
- else
- tx_mode1 <= TX_MODE_IDLE;
- default: tx_mode1 <= TX_MODE_IDLE;
- endcase
+ // capture the rx_byte_cnt values when write is done. TODO: needs to be a shallow Q to match FIFO
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
+ i_rx0_byte_cnt <= 'h0;
+ else if ( rx_wr_done[0])
+ i_rx0_byte_cnt <= rx0_byte_cnt;
-// TX1 data mux
-always @(*) begin
- case(tx1_src_sel)
- SEL_PHY0: tx_d1 = rx_d_01;
- SEL_PHY1: tx_d1 = 9'h000;
- SEL_PHY2: tx_d1 = rx_d_21;
- SEL_UC: tx_d1 = 9'h000;
- default: tx_d1 = 9'h000;
- endcase
-end
-
-// TX1 FIFO read enable
-always @(*) begin
- rx_fifo_re_01 = 1'b0;
- rx_fifo_re_21 = 1'b0;
- case(tx1_src_sel)
- SEL_PHY0: rx_fifo_re_01 = tx_fifo_re[1];
- SEL_PHY2: rx_fifo_re_21 = tx_fifo_re[1];
- endcase
-end
-
-// TX1 FIFO Empty Routing
-always @(*) begin
- case(tx1_src_sel)
- SEL_PHY0: tx_fifo_empty[1] = rx_fifo_empty_01;
- SEL_PHY1: tx_fifo_empty[1] = 1'b1;
- SEL_PHY2: tx_fifo_empty[1] = rx_fifo_empty_21;
- SEL_UC: tx_fifo_empty[1] = 1'b1;
- default: tx_fifo_empty[1] = 1'b1;
- endcase
-end
-
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
+ i_rx1_byte_cnt <= 'h0;
+ else if ( rx_wr_done[1])
+ i_rx1_byte_cnt <= rx1_byte_cnt;
+
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
+ i_rx2_byte_cnt <= 'h0;
+ else if ( rx_wr_done[2])
+ i_rx2_byte_cnt <= rx2_byte_cnt;
+
+ assign ipg_met = ipg_cnt >= IPG ? 1'b1 : 1'b0;
+
+ /* free running 100Mbit counter */
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
+ fr_100mbit_cnt <= 4'd0;
+ else if ( fr_100mbit_cnt == 4'd9 )
+ fr_100mbit_cnt <= 4'd0;
+ else
+ fr_100mbit_cnt <= fr_100mbit_cnt + 1'b1;
+
+ /* IPG counter */
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
+ ipg_cnt <= 7'd0;
+ else if ( tx_f[0] && tx_mode0 >= TX_MODE_XMT_PKT )
+ ipg_cnt <= 7'd0;
+ else if ( mode_100Mbit[0] && fr_100mbit_cnt == 4'd9 && !ipg_met )
+ ipg_cnt <= ipg_cnt + 1;
+ else if ( !mode_100Mbit[0] && !ipg_met )
+ ipg_cnt <= ipg_cnt + 1'b1;
+
+
+ // Transfer to the pclk domain
+ always @(posedge clk, negedge rstn)
+ if ( !rstn ) begin
+ rx_fifo_empty_u0_m1 <= 1'b1;
+ rx_fifo_empty_u0_m2 <= 1'b1;
+ end
+ else begin
+ rx_fifo_empty_u0_m1 <= rx_fifo_empty_u0;
+ rx_fifo_empty_u0_m2 <= rx_fifo_empty_u0_m1;
+ end
+
-/*
- * TX2 Switch Logic
- * Possible Sources: 0, 1
- */
-always @(posedge clk, negedge rstn)
- if ( !rstn )
+ // TX0 Switch Logic
+ // Possible sources: u, mle, 1, 2
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
begin
- tx_mode2 <= TX_MODE_AN;
- tx2_src_sel <= SEL_PHY0;
+ tx_mode0 <= TX_MODE_AN;
+ tx0_src_sel <= TX_SRC_SEL_PHY1;
+ tx0_byte_cnt <= 'h0;
end
- else if ( tx_f[2] )
- case( tx_mode2 )
- TX_MODE_AN:
- if ( phy_up[2] )
- tx_mode2 <= TX_MODE_IDLE;
- TX_MODE_IDLE:
- if ( !phy_up[2] )
- tx_mode2 <= TX_MODE_AN;
- else if (tx2_src_sel==SEL_PHY0 && !rx_fifo_empty_12 )
+ else if ( tx_f[0] )
+ case( tx_mode0 )
+ TX_MODE_AN:
+ if ( phy_up[0] )
+ tx_mode0 <= TX_MODE_IDLE;
+ TX_MODE_IDLE:
+ if ( !phy_up[0] )
+ tx_mode0 <= TX_MODE_AN;
+ else if ( !ipg_met )
+ tx_mode0 <= TX_MODE_IDLE;
+ else if (!rx_fifo_empty_mle) // mle has data
+ begin
+ tx_mode0 <= TX_MODE_XMT_CUSTOM;
+ tx0_src_sel <= TX_SRC_SEL_MLE;
+ tx0_byte_cnt <= rx_mle_byte_cnt;
+ end
+ else if (!rx_fifo_empty_u0_m2 ) // controller has data
begin
- tx_mode2 <= TX_MODE_XMT_PKT;
- tx2_src_sel <= SEL_PHY1;
+ tx_mode0 <= TX_MODE_XMT_CUSTOM;
+ tx0_src_sel <= TX_SRC_SEL_UC;
+ tx0_byte_cnt <= rxu_byte_cnt;
end
- else if (!rx_fifo_empty_02 )
+ `ifdef PHY2_PRESENT
+ else if (tx0_src_sel==TX_SRC_SEL_PHY1 && !rx_fifo_empty_20 )
begin
- tx_mode2 <= TX_MODE_XMT_PKT;
- tx2_src_sel <= SEL_PHY0;
+ tx_mode0 <= TX_MODE_XMT_PKT;
+ tx0_src_sel <= TX_SRC_SEL_PHY2;
+ tx0_byte_cnt <= i_rx2_byte_cnt;
+ end
+ `endif
+ else if (!rx_fifo_empty_10 )
+ begin
+ tx_mode0 <= TX_MODE_XMT_PKT;
+ tx0_src_sel <= TX_SRC_SEL_PHY1;
+ tx0_byte_cnt <= i_rx1_byte_cnt;
end
- else if (!rx_fifo_empty_12 )
+ `ifdef PHY2_PRESENT
+ else if (!rx_fifo_empty_20 )
begin
- tx_mode2 <= TX_MODE_XMT_PKT;
- tx2_src_sel <= SEL_PHY1;
+ tx_mode0 <= TX_MODE_XMT_PKT;
+ tx0_src_sel <= TX_SRC_SEL_PHY2;
+ tx0_byte_cnt <= i_rx2_byte_cnt;
end
- TX_MODE_XMT_PKT:
- if ( !phy_up[2] )
- tx_mode2 <= TX_MODE_AN;
- else
- tx_mode2 <= TX_MODE_IDLE;
- default: tx_mode2 <= TX_MODE_IDLE;
+ `endif
+ TX_MODE_XMT_PKT:
+ if ( !phy_up[0] )
+ tx_mode0 <= TX_MODE_AN;
+ else
+ tx_mode0 <= TX_MODE_IDLE;
+ default: tx_mode0 <= TX_MODE_IDLE;
+ endcase
+
+
+ // TX0 data mux
+ always @(*) begin
+ case(tx0_src_sel)
+ TX_SRC_SEL_PHY0: tx_d0 = 9'h000;
+ TX_SRC_SEL_PHY1: tx_d0 = rx_d_10;
+ TX_SRC_SEL_PHY2: tx_d0 = rx_d_20;
+ TX_SRC_SEL_MLE: tx_d0 = rx_mle_fifo_d;
+ TX_SRC_SEL_UC: tx_d0 = rx_d_u0;
+ default: tx_d0 = 9'h000;
endcase
+ end
-// TX2 data mux
-always @(*) begin
- case(tx2_src_sel)
- SEL_PHY0: tx_d2 = rx_d_02;
- SEL_PHY1: tx_d2 = rx_d_12;
- SEL_PHY2: tx_d2 = 9'h000;
- default: tx_d2 = 9'h000;
- endcase
-end
-
-// TX2 FIFO read enable
-always @(*) begin
- rx_fifo_re_02 = 1'b0;
- rx_fifo_re_12 = 1'b0;
- case(tx2_src_sel)
- SEL_PHY0: rx_fifo_re_02 = tx_fifo_re[2];
- SEL_PHY1: rx_fifo_re_12 = tx_fifo_re[2];
- endcase
-end
+ // TX0 FIFO read enable
+ always @(*) begin
+ rx_fifo_re_10 = 1'b0;
+ rx_fifo_re_20 = 1'b0;
+ rx_fifo_re_mle = 1'b0;
+ rx_fifo_re_u0 = 1'b0;
-// TX2 FIFO Empty Routing
-always @(*) begin
- case(tx2_src_sel)
- SEL_PHY0: tx_fifo_empty[2] = rx_fifo_empty_02;
- SEL_PHY1: tx_fifo_empty[2] = rx_fifo_empty_12;
- SEL_PHY2: tx_fifo_empty[2] = 1'b0; //
- default: tx_fifo_empty[2] = 1'b1;
- endcase
-end
+ case(tx0_src_sel)
+ TX_SRC_SEL_PHY1: rx_fifo_re_10 = tx_fifo_re[0];
+ TX_SRC_SEL_PHY2: rx_fifo_re_20 = tx_fifo_re[0];
+ TX_SRC_SEL_MLE: rx_fifo_re_mle = tx_fifo_re[0];
+ TX_SRC_SEL_UC: rx_fifo_re_u0 = tx_fifo_re[0];
+ endcase
+ end
-
-
-/*
- * Transmit Logic for UC
- *
- * The only possible driver is PHY0
- *
- * We need to delay the fifo_we one clock since the DPRAM read data comes out one clock delayed
- */
+ // TX0 FIFO Empty Routing
+ always @(*) begin
+ case(tx0_src_sel)
+ TX_SRC_SEL_PHY1: tx_fifo_empty[0] = rx_fifo_empty_10;
+ TX_SRC_SEL_PHY2: tx_fifo_empty[0] = rx_fifo_empty_20;
+ TX_SRC_SEL_MLE: tx_fifo_empty[0] = rx_fifo_empty_mle;
+ TX_SRC_SEL_UC: tx_fifo_empty[0] = rx_fifo_empty_u0_m2;
+ default: tx_fifo_empty[0] = 1'b1;
+ endcase
+ end
-assign tx_du = rx_d_0u;
-
-always @(*)
- if ( !rx_fifo_empty_0u )
+ // TX1 Switch Logic
+ // Possible sources: 0, 2 in priority
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
begin
- i_tx_fifo_we_u = 1'b1;
- rx_fifo_re_0u = 1'b1;
- end
- else
- begin
- i_tx_fifo_we_u = 1'b0;
- rx_fifo_re_0u = 1'b0;
+ tx_mode1 <= TX_MODE_AN;
+ tx1_src_sel <= TX_SRC_SEL_PHY0;
+ tx1_byte_cnt <= 'h0;
end
+ else if ( tx_f[1] )
+ case( tx_mode1 )
+ TX_MODE_AN:
+ if ( phy_up[1] )
+ tx_mode1 <= TX_MODE_IDLE;
+ TX_MODE_IDLE:
+ if ( !phy_up[1] )
+ tx_mode1 <= TX_MODE_AN;
+ `ifdef PHY2_PRESENT
+ else if (tx1_src_sel==TX_SRC_SEL_PHY0 && !rx_fifo_empty_21 )
+ begin
+ tx_mode1 <= TX_MODE_XMT_PKT;
+ tx1_src_sel <= TX_SRC_SEL_PHY2;
+ tx1_byte_cnt <= i_rx1_byte_cnt;
+ end
+ `endif
+ else if (!rx_fifo_empty_01 )
+ begin
+ tx_mode1 <= TX_MODE_XMT_PKT;
+ tx1_src_sel <= TX_SRC_SEL_PHY0;
+ tx1_byte_cnt <= i_rx0_byte_cnt;
+ end
+ `ifdef PHY2_PRESENT
+ else if (!rx_fifo_empty_21 )
+ begin
+ tx_mode1 <= TX_MODE_XMT_PKT;
+ tx1_src_sel <= TX_SRC_SEL_PHY2;
+ tx1_byte_cnt <= i_rx1_byte_cnt;
+ end
+ `endif
+ TX_MODE_XMT_PKT:
+ if ( !phy_up[1] )
+ tx_mode1 <= TX_MODE_AN;
+ else
+ tx_mode1 <= TX_MODE_IDLE;
+ default: tx_mode1 <= TX_MODE_IDLE;
+ endcase
+
+ // TX1 data mux
+ always @(*) begin
+ case(tx1_src_sel)
+ TX_SRC_SEL_PHY0: tx_d1 = rx_d_01;
+ TX_SRC_SEL_PHY1: tx_d1 = 9'h000;
+ TX_SRC_SEL_PHY2: tx_d1 = rx_d_21;
+ TX_SRC_SEL_UC: tx_d1 = 9'h000;
+ default: tx_d1 = 9'h000;
+ endcase
+ end
+
+ // TX1 FIFO read enable
+ always @(*) begin
+ rx_fifo_re_01 = 1'b0;
+ rx_fifo_re_21 = 1'b0;
+ case(tx1_src_sel)
+ TX_SRC_SEL_PHY0: rx_fifo_re_01 = tx_fifo_re[1];
+ TX_SRC_SEL_PHY2: rx_fifo_re_21 = tx_fifo_re[1];
+ endcase
+ end
+
+ // TX1 FIFO Empty Routing
+ always @(*) begin
+ case(tx1_src_sel)
+ TX_SRC_SEL_PHY0: tx_fifo_empty[1] = rx_fifo_empty_01;
+ TX_SRC_SEL_PHY1: tx_fifo_empty[1] = 1'b1;
+ TX_SRC_SEL_PHY2: tx_fifo_empty[1] = rx_fifo_empty_21;
+ TX_SRC_SEL_UC: tx_fifo_empty[1] = 1'b1;
+ default: tx_fifo_empty[1] = 1'b1;
+ endcase
+ end
+
-always @(posedge clk, negedge rstn)
- if ( !rstn )
- tx_fifo_we_u <= 1'b0;
- else
- tx_fifo_we_u <= i_tx_fifo_we_u;
+ // TX2 Switch Logic
+ // Possible sources: 0, 1
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
+ begin
+ tx_mode2 <= TX_MODE_AN;
+ tx2_src_sel <= TX_SRC_SEL_PHY0;
+ tx2_byte_cnt <= 'h0;
+ end
+ else if ( tx_f[2] )
+ case( tx_mode2 )
+ TX_MODE_AN:
+ if ( phy_up[2] )
+ tx_mode2 <= TX_MODE_IDLE;
+ TX_MODE_IDLE:
+ if ( !phy_up[2] )
+ tx_mode2 <= TX_MODE_AN;
+ else if (tx2_src_sel==TX_SRC_SEL_PHY0 && !rx_fifo_empty_12 )
+ begin
+ tx_mode2 <= TX_MODE_XMT_PKT;
+ tx2_src_sel <= TX_SRC_SEL_PHY1;
+ tx2_byte_cnt <= i_rx1_byte_cnt;
+ end
+ else if (!rx_fifo_empty_02 )
+ begin
+ tx_mode2 <= TX_MODE_XMT_PKT;
+ tx2_src_sel <= TX_SRC_SEL_PHY0;
+ tx2_byte_cnt <= i_rx0_byte_cnt;
+ end
+ else if (!rx_fifo_empty_12 )
+ begin
+ tx_mode2 <= TX_MODE_XMT_PKT;
+ tx2_src_sel <= TX_SRC_SEL_PHY1;
+ tx2_byte_cnt <= i_rx1_byte_cnt;
+ end
+ TX_MODE_XMT_PKT:
+ if ( !phy_up[2] )
+ tx_mode2 <= TX_MODE_AN;
+ else
+ tx_mode2 <= TX_MODE_IDLE;
+ default: tx_mode2 <= TX_MODE_IDLE;
+ endcase
+
+ // TX2 data mux
+ always @(*) begin
+ case(tx2_src_sel)
+ TX_SRC_SEL_PHY0: tx_d2 = rx_d_02;
+ TX_SRC_SEL_PHY1: tx_d2 = rx_d_12;
+ TX_SRC_SEL_PHY2: tx_d2 = 9'h000;
+ default: tx_d2 = 9'h000;
+ endcase
+ end
+
+ // TX2 FIFO read enable
+ always @(*) begin
+ rx_fifo_re_02 = 1'b0;
+ rx_fifo_re_12 = 1'b0;
+ case(tx2_src_sel)
+ TX_SRC_SEL_PHY0: rx_fifo_re_02 = tx_fifo_re[2];
+ TX_SRC_SEL_PHY1: rx_fifo_re_12 = tx_fifo_re[2];
+ endcase
+ end
+
+ // TX2 FIFO Empty Routing
+ always @(*) begin
+ case(tx2_src_sel)
+ TX_SRC_SEL_PHY0: tx_fifo_empty[2] = rx_fifo_empty_02;
+ TX_SRC_SEL_PHY1: tx_fifo_empty[2] = rx_fifo_empty_12;
+ TX_SRC_SEL_PHY2: tx_fifo_empty[2] = 1'b0; //
+ default: tx_fifo_empty[2] = 1'b1;
+ endcase
+ end
+
+
+
+ /*
+ * Transmit Logic for UC
+ *
+ * The only possible driver is PHY0
+ *
+ * We need to delay the fifo_we one clock since the DPRAM read data comes out one clock delayed
+ */
+
+ assign tx_du = rx_d_0u;
+
+ always @(*)
+ if ( !rx_fifo_empty_0u )
+ begin
+ i_tx_fifo_we_u = 1'b1;
+ rx_fifo_re_0u = 1'b1;
+ end
+ else
+ begin
+ i_tx_fifo_we_u = 1'b0;
+ rx_fifo_re_0u = 1'b0;
+ end
+
+ always @(posedge clk, negedge rstn)
+ if ( !rstn )
+ tx_fifo_we_u <= 1'b0;
+ else
+ tx_fifo_we_u <= i_tx_fifo_we_u;
endmodule \ No newline at end of file

Highly Recommended Verilog Books