diff options
Diffstat (limited to 'source/switch.v')
-rw-r--r-- | source/switch.v | 165 |
1 files changed, 108 insertions, 57 deletions
diff --git a/source/switch.v b/source/switch.v index f929b68..98aec4a 100644 --- a/source/switch.v +++ b/source/switch.v @@ -1,7 +1,7 @@ /* * switch.v * - * Copyright (C) 2018, 2019 Mind Chasers Inc. + * Copyright 2018, 2019, 2020, 2021 Mind Chasers Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * function: switch packet paths from RX to TX + * function: Soft Ethernet Switch * */ @@ -59,6 +59,13 @@ module switch( input rx_fifo_empty_30, rx_fifo_empty_31, rx_fifo_empty_32, input rx_fifo_empty_u2, + // RX Byte Count + input [3:0] rx_wr_done, + input [10:0] rx0_byte_cnt, + input [10:0] rx1_byte_cnt, + input [10:0] rx2_byte_cnt, + input [10:0] rx3_byte_cnt, + // TX FIFO output from internal muxes output reg [8:0] tx_d0, output reg [8:0] tx_d1, @@ -74,23 +81,30 @@ module switch( output reg [3:0] tx_fifo_empty, // TX modes for the PHYs and uc - output reg [1:0] tx_mode0, - output reg [1:0] tx_mode1, - output reg [1:0] tx_mode2, - output reg [1:0] tx_mode3, + output reg [2:0] tx_mode0, + output reg [2:0] tx_mode1, + output reg [2:0] tx_mode2, + output reg [2:0] tx_mode3, output reg tx_modeu, + // TX byte cnt + output reg [10:0] tx0_byte_cnt, + output reg [10:0] tx1_byte_cnt, + output reg [10:0] tx2_byte_cnt, + output reg [10:0] tx3_byte_cnt, + + // TX Source Select + output reg [2:0] tx_src_sel0, + output reg [2:0] tx_src_sel1, + output reg [2:0] tx_src_sel2, + output reg [2:0] tx_src_sel3, + // TX state machine done flag input [3:0] tx_f, // TX custom packet - input tx_metrics + input tx_custom ); - -reg [2:0] tx0_src_sel; -reg [2:0] tx1_src_sel; -reg [2:0] tx2_src_sel; -reg [2:0] tx3_src_sel; // IPG for Port 0 wire ipg_met; @@ -99,6 +113,8 @@ 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, i_rx3_byte_cnt; + `include "ethernet_params.v" `include "sgmii_params.v" @@ -109,22 +125,44 @@ localparam SEL_PHY0 = 3'b000, 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; + +always @(posedge clk, negedge rstn) + if ( !rstn ) + i_rx3_byte_cnt <= 'h0; + else if ( rx_wr_done[3]) + i_rx3_byte_cnt <= rx3_byte_cnt; + assign ipg_met = ipg_cnt >= IPG ? 1'b1 : 1'b0; /* free running 100Mbit counter */ always @(posedge clk, negedge rstn) -begin 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; -end /* IPG counter */ always @(posedge clk, negedge rstn) -begin if ( !rstn ) ipg_cnt <= 7'd0; else if ( tx_f[0] && tx_mode0 >= TX_MODE_XMT_PKT ) @@ -133,7 +171,6 @@ begin ipg_cnt <= ipg_cnt + 1; else if ( !mode_100Mbit[0] && !ipg_met ) ipg_cnt <= ipg_cnt + 1; -end // TX0 Switch Logic @@ -142,32 +179,36 @@ always @(posedge clk, negedge rstn) if ( !rstn ) begin tx_mode0 <= TX_MODE_AN; - tx0_src_sel <= SEL_PHY1; + tx_src_sel0 <= SEL_PHY1; + tx0_byte_cnt <= 'h0; end else if ( tx_f[0] ) case( tx_mode0 ) TX_MODE_AN: - if ( phy_up[0] ) + 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 (tx0_src_sel==SEL_PHY1 && !rx_fifo_empty_20 ) + else if (tx_src_sel0==SEL_PHY1 && !rx_fifo_empty_20 ) begin - tx_mode0 <= TX_MODE_XMT_PKT; - tx0_src_sel <= SEL_PHY2; + tx_mode0 <= TX_MODE_XMT_CUSTOM; + tx_src_sel0 <= SEL_PHY2; + tx0_byte_cnt <= i_rx2_byte_cnt; end else if (!rx_fifo_empty_10 ) begin tx_mode0 <= TX_MODE_XMT_PKT; - tx0_src_sel <= SEL_PHY1; + tx_src_sel0 <= SEL_PHY1; + tx0_byte_cnt <= i_rx1_byte_cnt; end else if (!rx_fifo_empty_20 ) begin - tx_mode0 <= TX_MODE_XMT_PKT; - tx0_src_sel <= SEL_PHY2; + tx_mode0 <= TX_MODE_XMT_CUSTOM; + tx_src_sel0 <= SEL_PHY2; + tx0_byte_cnt <= i_rx2_byte_cnt; end TX_MODE_XMT_PKT: if ( !phy_up[0] ) @@ -179,7 +220,7 @@ always @(posedge clk, negedge rstn) // TX0 data mux always @(*) begin - case(tx0_src_sel) + case(tx_src_sel0) SEL_PHY0: tx_d0 = 9'h000; SEL_PHY1: tx_d0 = rx_d_10; SEL_PHY2: tx_d0 = rx_d_20; @@ -193,7 +234,7 @@ always @(*) begin rx_fifo_re_10 = 1'b0; rx_fifo_re_20 = 1'b0; rx_fifo_re_30 = 1'b0; - case(tx0_src_sel) + case(tx_src_sel0) SEL_PHY1: rx_fifo_re_10 = tx_fifo_re[0]; SEL_PHY2: rx_fifo_re_20 = tx_fifo_re[0]; SEL_PHY3: rx_fifo_re_30 = tx_fifo_re[0]; @@ -202,7 +243,7 @@ end // TX0 FIFO Empty Routing always @(*) begin - case(tx0_src_sel) + case(tx_src_sel0) SEL_PHY1: tx_fifo_empty[0] = rx_fifo_empty_10; SEL_PHY2: tx_fifo_empty[0] = rx_fifo_empty_20; SEL_PHY3: tx_fifo_empty[0] = rx_fifo_empty_30; @@ -211,12 +252,12 @@ always @(*) begin end // TX1 Switch Logic -// Possible sources: 0, 3 +// Possible sources: 0, 2, 3 in priority always @(posedge clk, negedge rstn) if ( !rstn ) begin tx_mode1 <= TX_MODE_AN; - tx1_src_sel <= SEL_PHY0; + tx_src_sel1 <= SEL_PHY0; end else if ( tx_f[1] ) case( tx_mode1 ) @@ -226,20 +267,30 @@ always @(posedge clk, negedge rstn) TX_MODE_IDLE: if ( !phy_up[1] ) tx_mode1 <= TX_MODE_AN; - else if (tx1_src_sel==SEL_PHY0 && !rx_fifo_empty_31 ) + else if (tx_src_sel1==SEL_PHY0 && !rx_fifo_empty_21 ) begin tx_mode1 <= TX_MODE_XMT_PKT; - tx1_src_sel <= SEL_PHY3; + tx_src_sel1 <= SEL_PHY2; + end + else if (tx_src_sel1==SEL_PHY0 && !rx_fifo_empty_31 ) + begin + tx_mode1 <= TX_MODE_XMT_PKT; + tx_src_sel1 <= SEL_PHY3; end else if (!rx_fifo_empty_01 ) begin tx_mode1 <= TX_MODE_XMT_PKT; - tx1_src_sel <= SEL_PHY0; + tx_src_sel1 <= SEL_PHY0; end + else if (!rx_fifo_empty_21 ) + begin + tx_mode1 <= TX_MODE_XMT_PKT; + tx_src_sel1 <= SEL_PHY2; + end else if (!rx_fifo_empty_31 ) begin tx_mode1 <= TX_MODE_XMT_PKT; - tx1_src_sel <= SEL_PHY3; + tx_src_sel1 <= SEL_PHY3; end TX_MODE_XMT_PKT: if ( !phy_up[1] ) @@ -251,7 +302,7 @@ always @(posedge clk, negedge rstn) // TX1 data mux always @(*) begin - case(tx1_src_sel) + case(tx_src_sel1) SEL_PHY0: tx_d1 = rx_d_01; SEL_PHY1: tx_d1 = 9'h000; SEL_PHY2: tx_d1 = rx_d_21; @@ -266,7 +317,7 @@ always @(*) begin rx_fifo_re_01 = 1'b0; rx_fifo_re_21 = 1'b0; rx_fifo_re_31 = 1'b0; - case(tx1_src_sel) + case(tx_src_sel1) SEL_PHY0: rx_fifo_re_01 = tx_fifo_re[1]; SEL_PHY2: rx_fifo_re_21 = tx_fifo_re[1]; SEL_PHY3: rx_fifo_re_31 = tx_fifo_re[1]; @@ -275,7 +326,7 @@ end // TX1 FIFO Empty Routing always @(*) begin - case(tx1_src_sel) + case(tx_src_sel1) 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; @@ -297,7 +348,7 @@ always @(posedge clk, negedge rstn) if ( !rstn ) begin tx_mode2 <= TX_MODE_AN; - tx2_src_sel <= SEL_PHY0; + tx_src_sel2 <= SEL_PHY0; end else if ( tx_f[2] ) case( tx_mode2 ) @@ -307,30 +358,30 @@ always @(posedge clk, negedge rstn) 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_src_sel2==SEL_PHY0 && !rx_fifo_empty_12 ) begin tx_mode2 <= TX_MODE_XMT_PKT; - tx2_src_sel <= SEL_PHY1; + tx_src_sel2 <= SEL_PHY1; end else if (!rx_fifo_empty_02 ) begin tx_mode2 <= TX_MODE_XMT_PKT; - tx2_src_sel <= SEL_PHY0; + tx_src_sel2 <= SEL_PHY0; end else if (!rx_fifo_empty_12 ) begin tx_mode2 <= TX_MODE_XMT_PKT; - tx2_src_sel <= SEL_PHY1; + tx_src_sel2 <= SEL_PHY1; end else if (!rx_fifo_empty_u2) begin tx_mode2 <= TX_MODE_XMT_PKT; - tx2_src_sel <= SEL_UC; + tx_src_sel2 <= SEL_UC; end - else if (tx_metrics) + else if (tx_custom) begin - tx_mode2 <= TX_MODE_XMT_METRICS; - tx2_src_sel <= SEL_PHY2; + tx_mode2 <= TX_MODE_XMT_CUSTOM; + tx_src_sel2 <= SEL_PHY2; end TX_MODE_XMT_PKT: if ( !phy_up[2] ) @@ -342,7 +393,7 @@ always @(posedge clk, negedge rstn) // TX2 data mux always @(*) begin - case(tx2_src_sel) + case(tx_src_sel2) SEL_PHY0: tx_d2 = rx_d_02; SEL_PHY1: tx_d2 = rx_d_12; SEL_PHY2: tx_d2 = 9'h000; @@ -356,7 +407,7 @@ always @(*) begin rx_fifo_re_02 = 1'b0; rx_fifo_re_12 = 1'b0; rx_fifo_re_u2 = 1'b0; - case(tx2_src_sel) + case(tx_src_sel2) SEL_PHY0: rx_fifo_re_02 = tx_fifo_re[2]; SEL_PHY1: rx_fifo_re_12 = tx_fifo_re[2]; SEL_UC: rx_fifo_re_u2 = tx_fifo_re[2]; @@ -365,10 +416,10 @@ end // TX2 FIFO Empty Routing always @(*) begin - case(tx2_src_sel) + case(tx_src_sel2) 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; // this is done for metrics. + SEL_PHY2: tx_fifo_empty[2] = 1'b0; // SEL_UC: tx_fifo_empty[2] = rx_fifo_empty_u2; default: tx_fifo_empty[2] = 1'b1; endcase @@ -381,7 +432,7 @@ always @(posedge clk, negedge rstn) if ( !rstn ) begin tx_mode3 <= TX_MODE_AN; - tx3_src_sel <= SEL_PHY1; + tx_src_sel3 <= SEL_PHY1; end else if ( tx_f[3] ) case( tx_mode3 ) @@ -391,20 +442,20 @@ always @(posedge clk, negedge rstn) TX_MODE_IDLE: if ( !phy_up[3] ) tx_mode3 <= TX_MODE_AN; - else if (tx3_src_sel==SEL_PHY1 && !rx_fifo_empty_03 ) + else if (tx_src_sel3==SEL_PHY1 && !rx_fifo_empty_03 ) begin tx_mode3 <= TX_MODE_XMT_PKT; - tx3_src_sel <= SEL_PHY0; + tx_src_sel3 <= SEL_PHY0; end else if (!rx_fifo_empty_13 ) begin tx_mode3 <= TX_MODE_XMT_PKT; - tx3_src_sel <= SEL_PHY1; + tx_src_sel3 <= SEL_PHY1; end else if (!rx_fifo_empty_03 ) begin tx_mode3 <= TX_MODE_XMT_PKT; - tx3_src_sel <= SEL_PHY0; + tx_src_sel3 <= SEL_PHY0; end TX_MODE_XMT_PKT: if ( !phy_up[3] ) @@ -416,7 +467,7 @@ always @(posedge clk, negedge rstn) // TX3 data mux always @(*) begin - case(tx3_src_sel) + case(tx_src_sel3) SEL_PHY0: tx_d3 = rx_d_03; SEL_PHY1: tx_d3 = rx_d_13; SEL_PHY2: tx_d3 = rx_d_23; @@ -431,7 +482,7 @@ always @(posedge clk, negedge rstn) rx_fifo_re_03 = 1'b0; rx_fifo_re_13 = 1'b0; rx_fifo_re_23 = 1'b0; - case(tx3_src_sel) + case(tx_src_sel3) SEL_PHY0: rx_fifo_re_03 = tx_fifo_re[3]; SEL_PHY1: rx_fifo_re_13 = tx_fifo_re[3]; SEL_PHY2: rx_fifo_re_23 = tx_fifo_re[3]; @@ -440,7 +491,7 @@ always @(posedge clk, negedge rstn) // TX3 FIFO Empty Routing always @(*) begin - case(tx3_src_sel) + case(tx_src_sel3) SEL_PHY0: tx_fifo_empty[3] = rx_fifo_empty_03; SEL_PHY1: tx_fifo_empty[3] = rx_fifo_empty_13; SEL_PHY2: tx_fifo_empty[3] = rx_fifo_empty_23; |