From 39306b14e1a9b983ec0b566a209bebe7f5efcc14 Mon Sep 17 00:00:00 2001
From: mindchasers <privateisland@mindchasers.com>
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(-)

(limited to 'source')

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