From 39306b14e1a9b983ec0b566a209bebe7f5efcc14 Mon Sep 17 00:00:00 2001 From: mindchasers Date: Thu, 19 Nov 2020 22:12:52 -0500 Subject: switch: add support for custom packets --- source/switch.v | 88 ++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 19 deletions(-) diff --git a/source/switch.v b/source/switch.v index f929b68..6d70c5b 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 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,17 +81,23 @@ 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 state machine done flag input [3:0] tx_f, // TX custom packet - input tx_metrics + input tx_custom ); reg [2:0] tx0_src_sel; @@ -99,6 +112,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 +124,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 +170,6 @@ begin ipg_cnt <= ipg_cnt + 1; else if ( !mode_100Mbit[0] && !ipg_met ) ipg_cnt <= ipg_cnt + 1; -end // TX0 Switch Logic @@ -143,11 +179,12 @@ always @(posedge clk, negedge 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] ) + if ( phy_up[0] ) tx_mode0 <= TX_MODE_IDLE; TX_MODE_IDLE: if ( !phy_up[0] ) @@ -156,18 +193,21 @@ always @(posedge clk, negedge rstn) tx_mode0 <= TX_MODE_IDLE; else if (tx0_src_sel==SEL_PHY1 && !rx_fifo_empty_20 ) begin - tx_mode0 <= TX_MODE_XMT_PKT; + tx_mode0 <= TX_MODE_XMT_CUSTOM; tx0_src_sel <= 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; + tx0_byte_cnt <= i_rx1_byte_cnt; end else if (!rx_fifo_empty_20 ) begin - tx_mode0 <= TX_MODE_XMT_PKT; + tx_mode0 <= TX_MODE_XMT_CUSTOM; tx0_src_sel <= SEL_PHY2; + tx0_byte_cnt <= i_rx2_byte_cnt; end TX_MODE_XMT_PKT: if ( !phy_up[0] ) @@ -211,7 +251,7 @@ 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 @@ -226,6 +266,11 @@ 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_21 ) + begin + tx_mode1 <= TX_MODE_XMT_PKT; + tx1_src_sel <= SEL_PHY2; + end else if (tx1_src_sel==SEL_PHY0 && !rx_fifo_empty_31 ) begin tx_mode1 <= TX_MODE_XMT_PKT; @@ -236,6 +281,11 @@ always @(posedge clk, negedge rstn) tx_mode1 <= TX_MODE_XMT_PKT; tx1_src_sel <= SEL_PHY0; end + else if (!rx_fifo_empty_21 ) + begin + tx_mode1 <= TX_MODE_XMT_PKT; + tx1_src_sel <= SEL_PHY2; + end else if (!rx_fifo_empty_31 ) begin tx_mode1 <= TX_MODE_XMT_PKT; @@ -327,9 +377,9 @@ always @(posedge clk, negedge rstn) tx_mode2 <= TX_MODE_XMT_PKT; tx2_src_sel <= SEL_UC; end - else if (tx_metrics) + else if (tx_custom) begin - tx_mode2 <= TX_MODE_XMT_METRICS; + tx_mode2 <= TX_MODE_XMT_CUSTOM; tx2_src_sel <= SEL_PHY2; end TX_MODE_XMT_PKT: @@ -368,7 +418,7 @@ 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; // 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 @@ -477,4 +527,4 @@ always @(posedge clk, negedge rstn) tx_fifo_we_u <= i_tx_fifo_we_u; -endmodule +endmodule \ No newline at end of file -- cgit v1.2.3-8-gadcc