diff options
Diffstat (limited to 'source/switch.v')
| -rw-r--r-- | source/switch.v | 531 |
1 files changed, 0 insertions, 531 deletions
diff --git a/source/switch.v b/source/switch.v deleted file mode 100644 index 98aec4a..0000000 --- a/source/switch.v +++ /dev/null @@ -1,531 +0,0 @@ -/* - * switch.v - * - * 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * function: Soft Ethernet Switch - * - */ - -`timescale 1ns /10ps - -module switch( - input rstn, - input clk, - - // PHY status - input [3:0] phy_up, - input [3:0] mode_100Mbit, - - // FIFO input data from RX FIFOs - input [8:0] rx_d_01, - input [8:0] rx_d_02, - input [8:0] rx_d_03, - input [8:0] rx_d_10, - input [8:0] rx_d_12, - input [8:0] rx_d_13, - input [8:0] rx_d_20, - input [8:0] rx_d_21, - input [8:0] rx_d_23, - input [8:0] rx_d_2u, - input [8:0] rx_d_30, - input [8:0] rx_d_31, - input [8:0] rx_d_32, - input [8:0] rx_d_u2, - - // RX FIFO read enables - output reg rx_fifo_re_01, rx_fifo_re_02, rx_fifo_re_03, - output reg rx_fifo_re_10, rx_fifo_re_12, rx_fifo_re_13, - output reg rx_fifo_re_20, rx_fifo_re_21, rx_fifo_re_23, rx_fifo_re_2u, - output reg rx_fifo_re_30, rx_fifo_re_31, rx_fifo_re_32, - output reg rx_fifo_re_u2, - - // RX FIFO Empty flags - input rx_fifo_empty_01, rx_fifo_empty_02, rx_fifo_empty_03, - input rx_fifo_empty_10, rx_fifo_empty_12, rx_fifo_empty_13, - input rx_fifo_empty_20, rx_fifo_empty_21, rx_fifo_empty_23, rx_fifo_empty_2u, - 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, - output reg [8:0] tx_d2, - output reg [8:0] tx_d3, - output [8:0] tx_du, - - // TX FIFO read enable inputs (need to route to RX output FIFOs) - input [3:0] tx_fifo_re, - output reg tx_fifo_we_u, - - // TX FIFO Empty Flags (need to route to RX output FIFOs) - output reg [3:0] tx_fifo_empty, - - // TX modes for the PHYs and uc - 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_custom -); - -// IPG for Port 0 -wire ipg_met; -reg [6:0] ipg_cnt; -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" - -localparam SEL_PHY0 = 3'b000, - SEL_PHY1 = 3'b001, - SEL_PHY2 = 3'b010, - SEL_PHY3 = 3'b011, - 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) - 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; - -/* 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; - - -// TX0 Switch Logic -// Possible sources: 1, 2 -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode0 <= TX_MODE_AN; - 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] ) - 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 (tx_src_sel0==SEL_PHY1 && !rx_fifo_empty_20 ) - begin - 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; - 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_CUSTOM; - tx_src_sel0 <= SEL_PHY2; - tx0_byte_cnt <= i_rx2_byte_cnt; - end - 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(tx_src_sel0) - SEL_PHY0: tx_d0 = 9'h000; - SEL_PHY1: tx_d0 = rx_d_10; - SEL_PHY2: tx_d0 = rx_d_20; - SEL_UC: tx_d0 = 9'h000; - 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_30 = 1'b0; - 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]; - endcase -end - -// TX0 FIFO Empty Routing -always @(*) begin - 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; - default: tx_fifo_empty[0] = 1'b1; - endcase -end - -// TX1 Switch Logic -// Possible sources: 0, 2, 3 in priority -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode1 <= TX_MODE_AN; - tx_src_sel1 <= 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; - else if (tx_src_sel1==SEL_PHY0 && !rx_fifo_empty_21 ) - begin - tx_mode1 <= TX_MODE_XMT_PKT; - 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; - 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; - tx_src_sel1 <= SEL_PHY3; - end - 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(tx_src_sel1) - SEL_PHY0: tx_d1 = rx_d_01; - SEL_PHY1: tx_d1 = 9'h000; - SEL_PHY2: tx_d1 = rx_d_21; - SEL_PHY3: tx_d1 = rx_d_31; - 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; - rx_fifo_re_31 = 1'b0; - 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]; - endcase -end - -// TX1 FIFO Empty Routing -always @(*) begin - 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; - SEL_PHY3: tx_fifo_empty[1] = rx_fifo_empty_31; - SEL_UC: tx_fifo_empty[1] = 1'b1; - default: tx_fifo_empty[1] = 1'b1; - endcase -end - - -/* - * TX2 Switch Logic - * Possible Sources: 0, 1, UC - * Note that for TX_MODE_XMT_METRICS, we set the source to be loopback, but it is expected that the - * phy controller will use a combination of local memory and the metrics block for its data. These decisions - * should be revisited when implementing loopback within this switch module. - */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode2 <= TX_MODE_AN; - tx_src_sel2 <= SEL_PHY0; - 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 (tx_src_sel2==SEL_PHY0 && !rx_fifo_empty_12 ) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_PHY1; - end - else if (!rx_fifo_empty_02 ) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_PHY0; - end - else if (!rx_fifo_empty_12 ) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_PHY1; - end - else if (!rx_fifo_empty_u2) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_UC; - end - else if (tx_custom) - begin - tx_mode2 <= TX_MODE_XMT_CUSTOM; - tx_src_sel2 <= SEL_PHY2; - 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(tx_src_sel2) - SEL_PHY0: tx_d2 = rx_d_02; - SEL_PHY1: tx_d2 = rx_d_12; - SEL_PHY2: tx_d2 = 9'h000; - SEL_UC: tx_d2 = rx_d_u2; - 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; - rx_fifo_re_u2 = 1'b0; - 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]; - endcase -end - -// TX2 FIFO Empty Routing -always @(*) begin - 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; // - SEL_UC: tx_fifo_empty[2] = rx_fifo_empty_u2; - default: tx_fifo_empty[2] = 1'b1; - endcase -end - - -// TX3 Switch Logic -// Possible sources: 0, 1 -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode3 <= TX_MODE_AN; - tx_src_sel3 <= SEL_PHY1; - end - else if ( tx_f[3] ) - case( tx_mode3 ) - TX_MODE_AN: - if ( phy_up[3] ) - tx_mode3 <= TX_MODE_IDLE; - TX_MODE_IDLE: - if ( !phy_up[3] ) - tx_mode3 <= TX_MODE_AN; - else if (tx_src_sel3==SEL_PHY1 && !rx_fifo_empty_03 ) - begin - tx_mode3 <= TX_MODE_XMT_PKT; - tx_src_sel3 <= SEL_PHY0; - end - else if (!rx_fifo_empty_13 ) - begin - tx_mode3 <= TX_MODE_XMT_PKT; - tx_src_sel3 <= SEL_PHY1; - end - else if (!rx_fifo_empty_03 ) - begin - tx_mode3 <= TX_MODE_XMT_PKT; - tx_src_sel3 <= SEL_PHY0; - end - TX_MODE_XMT_PKT: - if ( !phy_up[3] ) - tx_mode3 <= TX_MODE_AN; - else - tx_mode3 <= TX_MODE_IDLE; - default: tx_mode3 <= TX_MODE_IDLE; - endcase - - // TX3 data mux - always @(*) begin - 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; - SEL_PHY3: tx_d3 = 9'h000; - SEL_UC: tx_d3 = 9'h000; - default: tx_d3 = 9'h000; - endcase - end - - // TX3 FIFO read enable - always @(*) begin - rx_fifo_re_03 = 1'b0; - rx_fifo_re_13 = 1'b0; - rx_fifo_re_23 = 1'b0; - 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]; - endcase - end - - // TX3 FIFO Empty Routing - always @(*) begin - 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; - default: tx_fifo_empty[3] = 1'b1; - endcase - end - -/* - * Transmit Logic for UC - * - * The only possible driver is PHY2 - * - * We need to delay the fifo_we one clock since the DPRAM read data comes out one clock delayed - */ - -assign tx_du = rx_d_2u; - -always @(*) - if ( !rx_fifo_empty_2u ) - begin - i_tx_fifo_we_u = 1'b1; - rx_fifo_re_2u = 1'b1; - end - else - begin - i_tx_fifo_we_u = 1'b0; - rx_fifo_re_2u = 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 |



