diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/an.v | 122 | ||||
-rw-r--r-- | source/controller.v | 20 | ||||
-rw-r--r-- | source/directives.v (renamed from source/definitions.v) | 20 | ||||
-rw-r--r-- | source/drop2_fifo.v | 255 | ||||
-rw-r--r-- | source/drop_fifo.v | 188 | ||||
-rw-r--r-- | source/ethernet_params.v | 13 | ||||
-rw-r--r-- | source/link_timer.v | 67 | ||||
-rw-r--r-- | source/mac.v | 380 | ||||
-rw-r--r-- | source/pcs.v | 228 | ||||
-rw-r--r-- | source/pkt_filter.v | 6 | ||||
-rw-r--r-- | source/sgmii_params.v | 9 | ||||
-rw-r--r-- | source/spi.v | 63 | ||||
-rw-r--r-- | source/switch.v | 165 | ||||
-rw-r--r-- | source/sync2_fifo.v | 141 | ||||
-rw-r--r-- | source/sync4_fifo.v | 206 | ||||
-rw-r--r-- | source/top.v | 2177 |
16 files changed, 677 insertions, 3383 deletions
diff --git a/source/an.v b/source/an.v new file mode 100644 index 0000000..18b5d95 --- /dev/null +++ b/source/an.v @@ -0,0 +1,122 @@ +/* + * an.v + * + * Copyright 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: Auto Negotiation + * + * Notes: a simplified version of AN suitable for SGMII only (not 1000BASE-SX) + */ + +`timescale 1ns /10ps + +module an( + input rstn, + input phy_resetn, // The external PHY has its reset signal asserted + input clk, + + // AN + input [1:0] phy_type, // SGMII==0, SX=1, SMA=3 + input pulse_1_6ms, // SGMII + input pulse_10ms, // SX + input [1:0] fixed_speed, + input an_disable, + output reg an_duplex, + output reg [1:0] an_speed, + output reg an_link_up, + output reg [15:0] tx_config_reg, + output reg phy_up, + + input rx_k_m1, + input rx_k_m2, + input rx_k_m3, + input rx_k_m4, + + input [7:0] rx_data_m1, + input [7:0] rx_data_m2, + input [7:0] rx_data_m3, + input [7:0] rx_data_m4 + + // Debug +); + +`include "sgmii_params.v" +`include "ethernet_params.v" + +localparam PHY_TYPE_SGMII = 2'b00, + PHY_TYPE_SX = 2'b01, + PHY_TYPE_RSVD = 2'b10, + PHY_TYPE_SMA = 2'b11; + + +localparam AN_TYPE_SX = 1'b0, + AN_TYPE_SGMII = 1'b1; + +localparam AN_ST_DISABLE=4'h0, AN_ST_ENABLE=4'h1, AN_ST_RESTART=4'h2, + AN_ST_ABILITY_DETECT=4'h3, AN_ST_ACK_DETECT=4'h4, + AN_ST_COMPLETE_ACK=4'h5, AN_ST_IDLE_DETECT=4'h6, AN_ST_LINK_OK=4'h7; + +// AN +reg [2:0] an_state; +wire an_ability_detect; +wire an_link_timer_pulse; +reg rx_config_detect; +reg [15:0] rx_config_reg, tx_config_reg; +reg [1:0] rx_config_cnt; // use to count consecutive rx config_regs + +/* + * SGMII Auto Negotiation State Machine + * Look for configuration /C/ ordered set + * /C/ is Alternating /C1/ and /C2/ + * /C1/: /K28.5/D21.5(0xb5)/Config_Reg + * /C2/: /K28.5/D2.2(0x42)/Config_Reg + * Config Reg: Low High + */ +always @(posedge clk or negedge rstn) + if (!rstn) + begin + an_link_up <= 1'b0; + an_duplex <= 1'b0; + an_speed <= SGMII_SPEED_RSVD; + phy_up <= 1'b0; + end + else if ( !phy_resetn ) + begin + an_link_up <= 1'b0; + an_duplex <= 1'b0; + an_speed <= SGMII_SPEED_RSVD; + phy_up <= 1'b0; + end + else if ( an_disable ) + begin + phy_up <= 1'b1; + end + // D21.5 is part of config ( M2 has low, M1 has high ) + else if (!rx_k_m1 && !rx_k_m2 && !rx_k_m3 && rx_data_m3 == D21_5 && rx_k_m4 && rx_data_m4 == K28_5 ) + begin + an_link_up <= rx_data_m1[7]; + an_duplex <= rx_data_m1[4]; + an_speed <= rx_data_m1[3:2]; + phy_up <= 1'b0; + end + // IDLE2 1:0xBC, 0:0x50 + else if ( !rx_k_m1 && rx_data_m1 == D16_2 && rx_k_m2 == 1'b1 && rx_data_m2 == K28_5 ) + phy_up <= 1'b1; + + +assign an_ability_detect = (rx_config_cnt == 2'd3 && rx_config_reg != 16'h0000 ); +assign link_timer_pulse = (phy_type == PHY_TYPE_SGMII && pulse_1_6ms) || (phy_type == PHY_TYPE_SX && pulse_10ms); + +endmodule diff --git a/source/controller.v b/source/controller.v index 6ede860..2b95d1e 100644 --- a/source/controller.v +++ b/source/controller.v @@ -1,7 +1,7 @@ /* * controller.v * - * Copyright (C) 2018, 2109 Mind Chasers Inc. + * Copyright (C) 2018, 2109, 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: FPGA internal controller + * function: FPGA internal state machine controller * */ @@ -74,10 +74,9 @@ module controller #(parameter ADDR_SZ = 7) output [3:0] rx_pcs_rst, output reg [1:0] mdio_mux_sel, - output i2c_fifo_priority, // TX custom packet - output reg tx_metrics + output reg tx_custom ); @@ -130,7 +129,6 @@ module controller #(parameter ADDR_SZ = 7) reg cont_start, cont_busy, cont_done; - assign i2c_fifo_priority = 1'b1; assign pcs_s = { pll_lol, pcs_rx_error }; assign link_s = port_up; @@ -247,7 +245,7 @@ module controller #(parameter ADDR_SZ = 7) mdio_routine_addr <= 'd80; end - // mdio_cont_busy and mux self + // mdio_cont_busy always @(posedge clk or negedge rstn) begin if ( !rstn ) @@ -397,15 +395,15 @@ module controller #(parameter ADDR_SZ = 7) mdio_mux_sel <= buffer[1][1:0]; end - /* transmit test packet */ + /* transmit custom packet */ always @(posedge clk or negedge rstn) begin if ( !rstn ) - tx_metrics <= 1'b0; + tx_custom <= 1'b0; else if ( rx_cmd && cmd == ASCIIt ) - tx_metrics <= 1'b1; + tx_custom <= 1'b1; else - tx_metrics <= 1'b0; + tx_custom <= 1'b0; end /* FIFO logic */ @@ -425,7 +423,7 @@ module controller #(parameter ADDR_SZ = 7) if ( !rstn ) read_fifo_d_o <= 0; else if ( cont_state == S2 && cmd == ASCIIp ) // pcs status - read_fifo_d_o <= { 2'b00, pcs_s }; + read_fifo_d_o <= { 1'b0, pcs_s }; else if ( cont_state == S2 && cmd == ASCIIl ) // link status read_fifo_d_o <= { 3'b000, link_s }; end diff --git a/source/definitions.v b/source/directives.v index ad600ff..5760c23 100644 --- a/source/definitions.v +++ b/source/directives.v @@ -1,7 +1,7 @@ /* - * definitions.v + * directives.v * - * Copyright 2(C) 018, 2019 Mind Chasers Inc. + * Copyright (C) 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,14 +15,20 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * function: misc. constants + * Description: misc. directives for board options * */ -// Debug Options (only enable at most one at a time) -`define DEBUG_I2C +// Debug Options for Darsena +//`define DEBUG_I2C //`define DEBUG_MDIO //`define DEBUG_SPI +//`define ARD_EXP_UART -// V02 boards can route UART to FT2232H -`define ARD_EXP_UART +`define DARSENA_V02 +//`define DARSENA_V03 + +// Shield Definition (PORTS 3 & 4) +//`define SHIELD_SMA_SMA +`define SHIELD_GIGE_SMA +//`define SHIELD_SFP_SMA diff --git a/source/drop2_fifo.v b/source/drop2_fifo.v deleted file mode 100644 index dcadd92..0000000 --- a/source/drop2_fifo.v +++ /dev/null @@ -1,255 +0,0 @@ -/* - * drop2_fifo.v - * - * Copyright (C) 2018, 2019 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: Double buffered side-by-side FIFO - * Uses 2 DPRAMs with additional logic for paths involving 1G to 100Mbit - * - */ - -`timescale 1ns /10ps - -module drop2_fifo( - input rstn, - input clk, - input enable, - - // control (drop, keep, and done are asserted for one clock ) - input keep, // this packet won't be dropped, start transferring it (KEEPS ARE AND'ED) - input passthrough, // don't store data, write through instead - - // input - input we_in, - input wr_done, - input [8:0] d_in, - - // output - output we_out, - output reg [8:0] d_out, - - // debug - output reg active -); - -// local parameters and includes - - -// nets and registers - -// the msbit of the ptr selects the DPRAM -reg [11:0] wr_ptr; -reg [11:0] rd_ptr; - -wire [8:0] d_out_0, d_out_1, d_out_internal; - -reg read_run, read_run_m1; // read continues while read_run is set -reg i_we_out, i_we_out_m1; // internal we_out -wire re; // read enable for dpram -reg rd_done_p1, rd_done; -wire i_keep; -reg kept; - -assign i_keep = keep & enable; - -wire dpram0_a_clk_e, dpram1_a_clk_e; -wire dpram0_b_clk_e, dpram1_b_clk_e; - -/* - * kept: assert for length of write duration after keep asserts - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - kept <= 1'b0; - else if ( wr_done ) - kept <= 1'b0; - else if ( i_keep ) - kept <= 1'b1; - -/* - * read_run logic - * read starts after wr_done - * continues until the FIFO is empty - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - begin - read_run <= 1'b0; - read_run_m1 <= 1'b0; - end - else if ( rd_done_p1 ) - begin - read_run <= 1'b0; - read_run_m1 <= 1'b0; - end - else if ( kept && wr_done ) - begin - read_run <= 1'b1; - end - else - read_run_m1 <= read_run; - -assign re = read_run; - -/* - * we_out logic - * delayed version of re - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - i_we_out <= 1'b0; - else if ( read_run && read_run_m1 ) - i_we_out <= 1'b1; - else - i_we_out <= 1'b0; - -always @(posedge clk, negedge rstn) - if( !rstn ) - i_we_out_m1 <= 1'b0; - else - i_we_out_m1 <= i_we_out; - -// OR these two signals to stretch we_out to the last byte from FIFO -assign we_out = i_we_out | i_we_out_m1; - -/* - * upper / lower half DPRAM logic - * directs upper or lower write buffer in FIFO - * toggle on each done event (rx_data is complete) - * don't toggle on a drop event (reuse buffer) - */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - wr_ptr[11] <= 1'b0; // init to the lower bank - else if ( wr_done && kept ) - wr_ptr[11] <= ~wr_ptr[11]; - -/* - * wr_ptr logic excluding msbit - * reset pointer when wr_done - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_ptr[10:0] <= 'd0; - else if ( wr_done ) - wr_ptr[10:0] <= 'd0; - else if ( we_in ) - wr_ptr[10:0] <= wr_ptr[10:0] + 1; - -/* - * each time the FIFO is empty, set rd_ptr[11] to wr_ptr[11] - * FIFO becomes empty through reading - */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - rd_ptr[11] <= 1'b0; // init to the lower bank - else if ( rd_done ) - rd_ptr[11] <= wr_ptr[11]; - -/* - * rd_ptr logic excluding msbit - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - rd_ptr[10:0] <= 'd0; - else if ( rd_done ) - rd_ptr[10:0] <= 'd0; - else if ( re ) - rd_ptr[10:0] <= rd_ptr[10:0] + 1; - -/* - * d_out register - * - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - d_out <= 'd0; - else - d_out <= d_out_internal; - - -/* -* rd_done logic -*/ -always @(posedge clk, negedge rstn) - if( !rstn ) - begin - rd_done_p1 <= 1'b0; - rd_done <= 1'b0; - end - else - begin - rd_done_p1 <= d_out_internal[8]; - rd_done <= rd_done_p1; - end - -// debug -always @(posedge clk, negedge rstn) - if( !rstn ) - active <= 1'b0; - else if ( we_in || we_out ) - active <= 1'b1; - else - active <= 1'b0; - -assign dpram0_a_clk_e = ~wr_ptr[11]; -assign dpram1_a_clk_e = wr_ptr[11]; - -assign dpram0_b_clk_e = ~rd_ptr[11]; -assign dpram1_b_clk_e = rd_ptr[11]; - -assign d_out_internal = dpram0_b_clk_e ? d_out_0 : d_out_1; - - -dpram dpram_0( -.rstn( rstn ), -.a_clk( clk ), -.a_clk_e( dpram0_a_clk_e ), -.a_we( we_in ), -.a_oe( 1'b0 ), -.a_addr( wr_ptr[10:0] ), -.a_din( d_in ), -.a_dout( ), -// port B -.b_clk( clk ), -.b_clk_e( dpram0_b_clk_e ), -.b_we( 1'b0 ), -.b_oe( re ), -.b_addr( rd_ptr[10:0] ), -.b_din( 9'h0 ), -.b_dout( d_out_0 ) -); - -dpram dpram_1( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( dpram1_a_clk_e ), - .a_we( we_in ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr[10:0] ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( dpram1_b_clk_e ), - .b_we( 1'b0 ), - .b_oe( re ), - .b_addr( rd_ptr[10:0] ), - .b_din( 9'h0 ), - .b_dout( d_out_1 ) -); - - -endmodule diff --git a/source/drop_fifo.v b/source/drop_fifo.v index 393c20b..736947c 100644 --- a/source/drop_fifo.v +++ b/source/drop_fifo.v @@ -1,7 +1,8 @@ /* * drop_fifo.v * - * Copyright (C) 2018, 2019 Mind Chasers Inc. + * Copyright 2018, 2019, 2020, 2021 Mind Chasers Inc. + * Copyright 2023 Private Island Networks Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,28 +16,27 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * function: Double buffered side-by-side FIFO for delaying data until keep / drop decision is made + * function: FIFO that supports dropping data if not kept + * + * For more information, see https://privateisland.tech/dev/pi-doc * */ -`timescale 1ns /10ps - module drop_fifo( input rstn, input clk, - input enable, - - // control (keep or drop by default) - input keep, // this packet won't be dropped, start transferring it input passthrough, // don't store / delay data, write through instead + input enable, // enable the FIFO + input keep, // this packet won't be dropped, start transferring it (writer must be sure FIFO won't run dry during writes) - // input + // input data input we_in, - input wr_done, - input [8:0] d_in, - - // output - output we_out, + input [8:0] d_in, + input wr_done, // keep should occur before wr_done is asserted. + input rx_eop, + + // output data + output reg we_out, output reg [8:0] d_out, // debug @@ -47,120 +47,92 @@ module drop_fifo( // nets and registers - -// the msbit of the ptr selects top or bottom half -reg [10:0] wr_ptr; +reg [10:0] wr_ptr0, wr_ptr1; // wr_ptr0 is updated on each write; wr_ptr1 is updated at end of packet reg [10:0] rd_ptr; - wire [8:0] d_out_internal; - -reg read_run, read_run_m1; // read continues while read_run is set -reg i_we_out, i_we_out_m1; // internal we_out -wire re; // read enable for dpram -reg rd_done_p1, rd_done; -wire i_keep; +reg read_run, read_run_m1, read_run_m2; // read continues while read_run is set reg kept; +wire fifo_empty; -assign i_keep = keep & enable; +/* + * kept: assert for length of write duration after keep asserts (when enable is active) + */ +always @(posedge clk, negedge rstn) + if( !rstn ) + kept <= 1'b0; + else if ( wr_done ) + kept <= 1'b0; + else if ( keep && enable ) + kept <= 1'b1; /* - * read_run logic - * read starts after each keep assertion - * continues until the FIFO is empty + * wr_ptr0 logic */ always @(posedge clk, negedge rstn) if( !rstn ) - read_run <= 1'b0; - else if ( rd_done_p1 ) - read_run <= 1'b0; - else if ( i_keep ) - read_run <= 1'b1; - - + wr_ptr0 <= 'd0; + else if ( we_in ) + wr_ptr0 <= wr_ptr0 + 1'b1; + +/* + * wr_ptr1 logic + * sync pointers at end of rx packet for next packet +*/ always @(posedge clk, negedge rstn) if( !rstn ) - read_run_m1 <= 1'b0; - else - read_run_m1 <= read_run; + wr_ptr1 <= 'd0; + else if ( wr_done ) + wr_ptr1 <= wr_ptr0 +1; // a write takes place with wr_done -assign re = read_run; - - /* - * we_out logic - * delayed version of re + * read_run logic + * continues until the FIFO is empty */ always @(posedge clk, negedge rstn) if( !rstn ) - i_we_out <= 1'b0; - else if ( read_run && read_run_m1 ) - i_we_out <= 1'b1; - else - i_we_out <= 1'b0; - + read_run <= 1'b0; + else if (kept && wr_done) + read_run <= 1'b1; + else if ( fifo_empty ) + read_run <= 1'b0; + + always @(posedge clk, negedge rstn) if( !rstn ) - i_we_out_m1 <= 1'b0; - else - i_we_out_m1 <= i_we_out; + read_run_m1 <= 1'b0; + else + read_run_m1 <= read_run; -// OR these two signals to stretch we_out to the last byte from FIFO -assign we_out = i_we_out | i_we_out_m1; -/* - * kept: assert for length of write duration after keep asserts - */ always @(posedge clk, negedge rstn) if( !rstn ) - kept <= 1'b0; - else if ( wr_done ) - kept <= 1'b0; - else if ( i_keep ) - kept <= 1'b1; - + read_run_m2 <= 1'b0; + else + read_run_m2 <= read_run_m1; + /* - * upper / lower half DPRAM logic - * directs upper or lower write buffer in FIFO - * toggle each time a packet is kept and write is finished - */ +* rd_ptr logic +*/ always @(posedge clk, negedge rstn) - if ( !rstn ) - wr_ptr[10] <= 1'b0; // init to the lower bank - else if ( wr_done && kept ) - wr_ptr[10] <= ~wr_ptr[10]; + if( !rstn ) + rd_ptr <= 'd0; + else if (kept && wr_done) + rd_ptr <= wr_ptr1; // set rd_ptr to the beginning of where the write started + else if (read_run && !fifo_empty) + rd_ptr <= rd_ptr+ 1'b1; /* - * wr_ptr logic excluding msbit - * reset pointer when wr_done + * we_out logic */ always @(posedge clk, negedge rstn) if( !rstn ) - wr_ptr[9:0] <= 'd0; - else if ( wr_done ) - wr_ptr[9:0] <= 'd0; - else if ( we_in ) - wr_ptr[9:0] <= wr_ptr[9:0] + 1; + we_out <= 1'b0; + else if ( read_run_m1 && read_run_m2 ) + we_out <= 1'b1; + else + we_out <= 1'b0; -/* - * each time the FIFO is empty, set rd_ptr[10] to wr_ptr[10] - * FIFO becomes empty through reading - */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - rd_ptr[10] <= 1'b0; // init to the lower bank - else if ( rd_done ) - rd_ptr[10] <= wr_ptr[10]; - -/* - * rd_ptr logic excluding msbit - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - rd_ptr[9:0] <= 'd0; - else if ( rd_done ) - rd_ptr[9:0] <= 'd0; - else if ( re ) - rd_ptr[9:0] <= rd_ptr[9:0] + 1; +assign fifo_empty = (wr_ptr1 == rd_ptr); /* * d_out register @@ -172,22 +144,6 @@ always @(posedge clk, negedge rstn) else d_out <= d_out_internal; - -/* -* rd_done logic -*/ -always @(posedge clk, negedge rstn) - if( !rstn ) - begin - rd_done_p1 <= 1'b0; - rd_done <= 1'b0; - end - else - begin - rd_done_p1 <= d_out_internal[8]; - rd_done <= rd_done_p1; - end - always @(posedge clk, negedge rstn) if( !rstn ) @@ -203,12 +159,12 @@ dpram dpram_fifo( .a_clk_e( 1'b1 ), .a_we( we_in ), .a_oe( 1'b0 ), -.a_addr( wr_ptr ), +.a_addr( wr_ptr0 ), .a_din( d_in ), .a_dout( ), // port B .b_clk( clk ), -.b_clk_e( re ), +.b_clk_e( read_run ), .b_we( 1'b0 ), .b_oe( 1'b1 ), .b_addr( rd_ptr ), diff --git a/source/ethernet_params.v b/source/ethernet_params.v index e974a05..dcb7dba 100644 --- a/source/ethernet_params.v +++ b/source/ethernet_params.v @@ -1,7 +1,7 @@ /* * ethernet_params.v * - * Copyright (C) 2018, 2019 Mind Chasers Inc. + * Copyright (C) 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. @@ -24,13 +24,14 @@ localparam MTU = 1520; // Ethernet is actually 1500+framing (max 18) localparam IPG = 96; // Inter-packet Gap Bits localparam SZ_ETH_HEADER = 14; // w/o VLAN -localparam SZ_IPV4_HEADER = 20; // w/o Options +localparam SZ_IPV4_HEADER = 20; // w/o Options localparam SZ_UDP_HEADER = 8; -localparam TX_MODE_AN = 2'b00, -TX_MODE_IDLE = 2'b01, -TX_MODE_XMT_PKT = 2'b10, // anything >= to this is a mode where a packet is transmitted -TX_MODE_XMT_METRICS = 2'b11; +localparam TX_MODE_AN = 3'b000, +TX_MODE_IDLE = 3'b001, +TX_MODE_XMT_PKT = 3'b010, // anything >= to this is a mode where a packet is transmitted +TX_MODE_XMT_METRICS = 3'b011, +TX_MODE_XMT_CUSTOM = 3'b100; // Note: The Length/Type field is transmitted and received with the high order octet first. localparam ETHER_TYPE_IPV4 = 16'h0800, diff --git a/source/link_timer.v b/source/link_timer.v new file mode 100644 index 0000000..7b501ff --- /dev/null +++ b/source/link_timer.v @@ -0,0 +1,67 @@ +/* + * link_timer.v + * + * Copyright 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. + * 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: Generate link timer pulse (1.6 and 10 ms) per SGMII and IEEE 802.3 + * + */ + +module link_timer( + input rstn, + input clk, // 125 MHz data clock + output pulse_1_6ms, + output pulse_10ms +); + + reg [13:0] cnt; // 0.1 ms counter + reg [3:0] cnt_1_6ms; + reg [6:0] cnt_10ms; + + // 0.1 ms counter + always @ (posedge clk or negedge rstn) + if ( !rstn ) + cnt <= 'd0; + else if (cnt == 'd12500) + cnt <= 'd0; + else + cnt <= cnt + 1; + + // 1.6 ms counter + always @ (posedge clk or negedge rstn) + if ( !rstn ) + cnt_1_6ms <= 'd0; + else if (cnt == 'd12500) + if (cnt_1_6ms == 'd16) + cnt_1_6ms <= 'd0; + else + cnt_1_6ms <= cnt_1_6ms + 1; + + assign pulse_1_6ms = (cnt == 'd12500 && cnt_1_6ms == 'd15); + + // 10 ms counter + always @ (posedge clk or negedge rstn) + if ( !rstn ) + cnt_10ms <= 'd0; + else if (cnt == 'd12500) + if (cnt_10ms == 'd99) + cnt_10ms <= 'd0; + else + cnt_10ms <= cnt_10ms + 1; + + assign pulse_10ms = (cnt == 'd12500 && cnt_10ms == 'd99); + + +endmodule
\ No newline at end of file diff --git a/source/mac.v b/source/mac.v index 8941710..b5b980a 100644 --- a/source/mac.v +++ b/source/mac.v @@ -1,7 +1,7 @@ /* * mac.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,38 +15,37 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * function: SGMII TX/RX/AN state machines + * function: Ethernet MAC Layer * */ -`timescale 1ns /10ps - module mac( input rstn, input phy_resetn, // The external PHY has its reset signal asserted input clk, input tap_port, - // SGMII AN - input link_timer, + // PCS / SERDES health + input rx_lsm, + input rx_cv_err, + input rx_disp_err, + input rx_cdr_lol, + input rx_los, + + // AN + input [1:0] phy_type, // SGMII==0, SX=1, SMA=3 + input pulse_1_6ms, // SGMII + input pulse_10ms, // SX input [1:0] fixed_speed, input an_disable, - output reg an_link_up, - output reg an_duplex, - output reg phy_up, + output an_duplex, + output phy_up, output reg mode_100Mbit, // Switch I/F - input [1:0] tx_mode, + input [2:0] tx_mode, output reg tx_f, - // PCS / SERDES health - input rx_lsm, - input rx_cv_err, - input rx_disp_err, - input rx_cdr_lol, - input rx_los, - // PCS data I/F input rx_k, input [7:0] rx_data, @@ -54,11 +53,6 @@ module mac( output reg [7:0] tx_data, output reg tx_disp_correct, - // Flags and Interrupts - output reg rx_enet_bcast, - output reg rx_ipv4_arp, - output keep, - // TX FCS output reg fcs_init, output reg fcs_enable, @@ -66,13 +60,18 @@ module mac( output reg [7:0] fcs_dout, input [7:0] fcs_din, - // SGMII RX / FIFO Write + // MAC RX / FIFO Write output rx_fifo_we, output [8:0] rx_fifo_d, output reg rx_error, + output rx_keep, output reg rx_wr_done, + output reg [10:0] rx_byte_cnt, + output [1:0] rx_mode, - // SGMII TX / FIFO Read + // MAC TX / FIFO Read + input [10:0] tx_byte_cnt_i, + input [2:0] tx_src_sel, output reg tx_fifo_re, input [8:0] tx_fifo_d, input tx_fifo_empty, @@ -82,7 +81,6 @@ module mac( output reg ipv4_pkt_start, output reg trigger, - output reg rx_k_m1, output reg rx_k_m2, output reg rx_k_m3, @@ -93,14 +91,16 @@ module mac( output reg[7:0] rx_data_m3, output reg[7:0] rx_data_m4, - // Param RAM for TAP port + // Param RAM output [10:0] dpr_ad, output dpr_we, output dpr_ce, input [8:0] dpr_di, output [8:0] dpr_do, - // Metrics and Interrupts + // Flags, Metrics, Interrupts, and Debug + output reg rx_enet_bcast, + output reg rx_ipv4_arp, output reg mac_int, output reg rx_sop, // start of packet output reg rx_eop, @@ -108,19 +108,22 @@ module mac( output reg tx_eop, output reg metrics_start, input [8:0] metrics_d, - - // Debug output reg rx_active, output reg tx_active ); `include "sgmii_params.v" `include "ethernet_params.v" - + +localparam PHY_TYPE_SGMII = 2'b00, + PHY_TYPE_SX = 2'b01, + PHY_TYPE_RSVD = 2'b10, + PHY_TYPE_SMA = 2'b11; + localparam AN_TX_CONFIG_HI = 8'h00, AN_TX_CONFIG_HI_ACK = 8'h40, - AN_TX_CONFIG_LO = 8'h01; - + AN_TX_CONFIG_LO = 8'h21; + localparam RX_ST_IDLE=4'h0, RX_ST_SOP=4'h1, RX_ST_PREAMBLE=4'h2, RX_ST_SFD=4'h3, RX_ST_MAC_ADDR=4'h4, RX_ST_MAC_TYPE0=4'h5, RX_ST_MAC_TYPE1=4'h6, RX_ST_DATA=4'h7, RX_ST_DATA_DONE0=4'h8, RX_ST_DATA_DONE1=4'h9, RX_ST_DATA_DONE2=4'ha; @@ -130,27 +133,30 @@ localparam TX_ST_0=4'h0, TX_ST_1=4'h1, TX_ST_2=4'h2, TX_ST_3=4'h3, TX_ST_8=4'h8, TX_ST_9=4'h9, TX_ST_A=4'ha, TX_ST_B=4'hb, TX_ST_C=4'hc, TX_ST_D=4'hd, TX_ST_E=4'he, TX_ST_F=4'hf; -reg [3:0] rx_cnt_100mbit, tx_cnt_100mbit; +// AN +wire [15:0] tx_config_reg; +wire [1:0] an_speed; +reg [3:0] rx_cnt_100mbit, tx_cnt_100mbit; wire tx_sample, tx_sample_re; wire rx_packet_complete; wire mode_1Gbit; -reg [1:0] an_speed; reg [3:0] rx_state; -reg [10:0] rx_byte_cnt; reg [10:0] rx_pkt_length; reg [15:0] rx_l3_proto; +// TODO: consider reorganizing state machines to reuse registers. reg [7:0] tx_data_an, tx_data_idle, tx_data_pkt; reg tx_k_an, tx_k_idle, tx_k_pkt; // Transmit Registers and Wires reg [3:0] tx_state; // transmit state machine reg [10:0] tx_byte_cnt; -reg [5:0] param_addr; +reg [10:0] param_addr; reg tx_f_an, tx_f_idle, tx_f_pkt; +reg i_tx_disp_correct; reg tx_last_byte; // FIFOs: @@ -165,6 +171,16 @@ reg [8:0] dpr_di_reg; // counter for detecting Ethernet broadcast, only needs to count to 6 reg [2:0] rx_enet_bcast_cnt; +// layer 3 TX support +reg [18:0] tx_ipv4_cksum; +reg [15:0] tx_ipv4_length; + +// layer 4 TX support +reg [15:0] tx_udp_length; + +wire tx_finished; +wire tx_temp; + /* * RX DIRECTION @@ -200,47 +216,34 @@ always @(posedge clk or negedge rstn) end end -/* - * SGMII Auto Negotiation State Machine - * Look for configuration /C/ ordered set - * /C/ is Alternating /C1/ and /C2/ - * /C1/: /K28.5/D21.5/Config_Reg - * /C2/: /K28.5/D2.2/Config_Reg - * Config Reg: Low High - * - * Not using a link timer and not counting 3 frames because testing rmshows it's unnecessary - * - */ -always @(posedge clk or negedge rstn) - if (!rstn) - begin - an_link_up <= 1'b0; - an_duplex <= 1'b0; - an_speed <= SGMII_SPEED_RSVD; - phy_up <= 1'b0; - end - else if ( !phy_resetn ) - begin - an_link_up <= 1'b0; - an_duplex <= 1'b0; - an_speed <= SGMII_SPEED_RSVD; - phy_up <= 1'b0; - end - else if ( an_disable ) - begin - phy_up <= 1'b1; - end - // D21.5 is part of config ( M2 has low, M1 has high ) - else if (!rx_k_m1 && !rx_k_m2 && !rx_k_m3 && rx_data_m3 == D21_5 && rx_k_m4 && rx_data_m4 == K28_5 ) - begin - an_link_up <= rx_data_m1[7]; - an_duplex <= rx_data_m1[4]; - an_speed <= rx_data_m1[3:2]; - phy_up <= 1'b0; - end - // IDLE2 1:0xBC, 0:0x50 - else if ( !rx_k_m1 && rx_data_m1 == D16_2 && rx_k_m2 == 1'b1 && rx_data_m2 == K28_5 ) - phy_up <= 1'b1; +// Auto Negotiation +an an_inst ( + .rstn(rstn), + .phy_resetn(phy_resetn), + .clk(clk), + // AN + .phy_type(phy_type), + .pulse_1_6ms(pulse_1_6ms), + .pulse_10ms(pulse_10ms), + .fixed_speed(fixed_speed), + .an_disable(an_disable), + .an_duplex(an_duplex), + .an_speed(an_speed), + .an_link_up(an_link_up), + .tx_config_reg(tx_config_reg), + .phy_up(phy_up), + + .rx_k_m1(rx_k_m1), + .rx_k_m2(rx_k_m2), + .rx_k_m3(rx_k_m3), + .rx_k_m4(rx_k_m4), + + .rx_data_m1(rx_data_m1), + .rx_data_m2(rx_data_m2), + .rx_data_m3(rx_data_m3), + .rx_data_m4(rx_data_m4) + ); + // 100 MBit Support. There are no plans to support 10 MBit, so 100 MBit inactive is the same as 1GBit active // if/else encodes the priority @@ -270,7 +273,8 @@ always @(posedge clk or negedge rstn) /* * rx_state machine * capture the Ethernet MAC header + packet. -*/ + * + */ always @(posedge clk, negedge rstn) if (!rstn) rx_state <= RX_ST_IDLE; @@ -310,9 +314,13 @@ always @(posedge clk, negedge rstn) */ assign rx_fifo_we = ( rx_sample && ( rx_state >= RX_ST_SFD && rx_state <= RX_ST_DATA_DONE1 ) ) ? 1'b1 : 1'b0; +// rx_mode +assign rx_mode = 2'b00; + /* * Detect Ethernet Broadcast (destination address = ff:ff:ff:ff:ff:ff) + * TODO: Add state information to only trigger on DEST ADDRESS * */ always @(posedge clk, negedge rstn) @@ -369,14 +377,14 @@ always @(posedge clk, negedge rstn) rx_ipv4_arp <= 1'b0; /* - * keep flag + * rx_keep flag * signals must be one shot * */ - assign keep = rx_enet_bcast | rx_ipv4_arp; - + assign rx_keep = rx_enet_bcast | rx_ipv4_arp; /* rx_error + * TODO: should be one shot? * */ always @(*) if ( rx_sample && rx_state >= RX_ST_DATA && ( rx_l3_proto != ETHER_TYPE_IPV4 && rx_l3_proto != ETHER_TYPE_IPV6 && rx_l3_proto != ETHER_TYPE_ARP) ) @@ -478,9 +486,10 @@ always @(posedge clk or negedge rstn) */ - // TX 100 Mbit support -assign tx_sample_re = (tx_cnt_100mbit == 4'd8 && mode_100Mbit) || !mode_100Mbit ? 1'b1 : 1'b0; -assign tx_sample = (tx_cnt_100mbit == 4'd9 && mode_100Mbit) || !mode_100Mbit ? 1'b1 : 1'b0; +// TX 100 Mbit support +assign tx_sample_re = (tx_cnt_100mbit == 4'd8 && mode_100Mbit) || !mode_100Mbit; +assign tx_sample = (tx_cnt_100mbit == 4'd9 && mode_100Mbit) || !mode_100Mbit; + always @(posedge clk or negedge rstn) if (!rstn) tx_cnt_100mbit <= 4'b0; @@ -496,41 +505,42 @@ always @(posedge clk or negedge rstn) * * Transmit Mux */ -always@(*) - begin +always @(posedge clk or negedge rstn) + if (!rstn) begin + tx_data <= 8'h00; + tx_k <= 1'b0; + tx_disp_correct <= 1'b0; + end + else begin case(tx_mode) - TX_MODE_AN : - begin - tx_data = tx_data_an; - tx_k = tx_k_an; - tx_f = tx_f_an; - end - TX_MODE_IDLE : - begin - tx_data = tx_data_idle; - tx_k = tx_k_idle; - tx_f = tx_f_idle; - end - TX_MODE_XMT_PKT : + TX_MODE_AN: begin - tx_data = tx_data_pkt; - tx_k = tx_k_pkt; - tx_f = tx_f_pkt; + tx_data <= tx_data_an; + tx_k <= tx_k_an; + tx_disp_correct <= i_tx_disp_correct; end - TX_MODE_XMT_METRICS : + TX_MODE_IDLE: begin - tx_data = tx_data_pkt; - tx_k = tx_k_pkt; - tx_f = tx_f_pkt; + tx_data <= tx_data_idle; + tx_k <= tx_k_idle; + tx_disp_correct <= i_tx_disp_correct; end - default : + default: begin - tx_data = K_ERROR; - tx_k = 1'b1; - tx_f = 1'b1; + tx_data <= tx_data_pkt; + tx_k <= tx_k_pkt; + tx_disp_correct <= i_tx_disp_correct; end endcase end + +// tx_f mux +always @(*) + case(tx_mode) + TX_MODE_AN: tx_f <= tx_f_an; + TX_MODE_IDLE: tx_f <= tx_f_idle; + default : tx_f <= tx_f_pkt; + endcase /* @@ -544,46 +554,46 @@ always @(*) tx_f_an = 1'b0; tx_k_an = 1'b0; case(tx_byte_cnt[2:0]) - 3'd0: - begin - tx_data_an = K28_5; - tx_k_an = 1'b1; - end - 3'd1: + 3'd0: + begin + tx_data_an = K28_5; + tx_k_an = 1'b1; + end + 3'd1: tx_data_an = D21_5; - 3'd2: + 3'd2: tx_data_an = AN_TX_CONFIG_LO; - 3'd3: + 3'd3: if (!an_link_up) tx_data_an = AN_TX_CONFIG_HI; - else + else tx_data_an = AN_TX_CONFIG_HI_ACK; - 3'd4: - begin - tx_data_an = K28_5; - tx_k_an = 1'b1; - end - 3'd5: + 3'd4: + begin + tx_data_an = K28_5; + tx_k_an = 1'b1; + end + 3'd5: tx_data_an = D2_2; - 3'd6: + 3'd6: tx_data_an = AN_TX_CONFIG_LO; - 3'd7: + 3'd7: if (!an_link_up) begin - tx_f_an = 1'b1; + tx_f_an = 1'b1; tx_data_an = AN_TX_CONFIG_HI; end else begin - tx_f_an = 1'b1; + tx_f_an = 1'b1; tx_data_an = AN_TX_CONFIG_HI_ACK; end default: - begin - tx_data_an = K_ERROR; - tx_k_an = 1'b1; - tx_f_an = 1'b1; - end + begin + tx_data_an = K_ERROR; + tx_k_an = 1'b1; + tx_f_an = 1'b1; + end endcase end @@ -613,16 +623,23 @@ always @(*) end +/* + * TX Finished Logic + */ +assign tx_temp = (tx_mode==TX_MODE_XMT_CUSTOM && tx_byte_cnt==tx_ipv4_length+SZ_ETH_HEADER); +assign tx_finished = tx_last_byte || (tx_mode==TX_MODE_XMT_CUSTOM && tx_byte_cnt==(tx_ipv4_length+SZ_ETH_HEADER)); + + /* -* Transmit Packet State Machine for TX_MODE_XMT_PKT and TX_MODE_XMT_METRICS +* Transmit Packet State Machine * * * Note: the first /I/ following a transmitted frame or Configuration ordered set * restores the current positive or negative running disparity to a -* negative value. -* +* negative value. +* */ always @(posedge clk, negedge rstn) begin @@ -640,9 +657,9 @@ always @(posedge clk, negedge rstn) tx_state <= TX_ST_3; // preamble 0x55, assert tx_fifo_re, reset tx_byte_cnt TX_ST_3: if ( tx_sample ) tx_state <= TX_ST_4; // preamble 0xD5 - TX_ST_4: if ( tx_sample && tx_last_byte && tx_byte_cnt < 60 ) // check if we need to pad? + TX_ST_4: if ( tx_sample && tx_finished && tx_byte_cnt < 60 ) // check if we need to pad? tx_state <= TX_ST_5; - else if ( tx_sample && (tx_fifo_empty || tx_last_byte) ) // check if we're done + else if ( tx_sample && tx_finished) // check if we're done tx_state <= TX_ST_6; TX_ST_5: if ( tx_sample && tx_byte_cnt >= 60 ) // pad state, test for sufficient frame size tx_state <= TX_ST_6; @@ -662,19 +679,18 @@ always @(posedge clk, negedge rstn) default: tx_state <= tx_state; endcase end - - - /* * tx related data mux and control signals +* TODO: add additional states for stuffing header values +* TODO: this will need to be registered at some point * */ always @(*) begin tx_f_pkt = 1'b0; tx_k_pkt = 1'b0; - tx_disp_correct = 1'b0; + i_tx_disp_correct = 1'b0; tx_last_byte = 1'b0; fcs_init = 1'b0; fcs_addr_e = 1'b0; @@ -698,7 +714,36 @@ always @(*) end TX_ST_4: begin - if ( tx_mode == TX_MODE_XMT_METRICS && tx_byte_cnt <= SZ_ETH_HEADER + SZ_IPV4_HEADER + SZ_UDP_HEADER ) + if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd17) begin + tx_data_pkt = tx_ipv4_length[15:8]; + fcs_dout = tx_ipv4_length[15:8]; + end + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd18) begin + tx_data_pkt = tx_ipv4_length[7:0]; + fcs_dout = tx_ipv4_length[7:0]; + end + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd25) begin + tx_data_pkt = tx_ipv4_cksum[15:8]; + fcs_dout = tx_ipv4_cksum[15:8]; + end + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd26) begin + tx_data_pkt = tx_ipv4_cksum[7:0]; + fcs_dout = tx_ipv4_cksum[7:0]; + end + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd38) begin + tx_data_pkt = 8'h0 + tx_src_sel[2]; // UDP destination port + fcs_dout = 8'h0 + tx_src_sel[2]; + end + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd39) begin + tx_data_pkt = tx_udp_length[15:8]; + fcs_dout = tx_udp_length[15:8]; + end + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd40) begin + tx_data_pkt = tx_udp_length[7:0]; + fcs_dout = tx_udp_length[7:0]; + end + else if ( (tx_mode == TX_MODE_XMT_METRICS || tx_mode == TX_MODE_XMT_CUSTOM) + && tx_byte_cnt <= SZ_ETH_HEADER + SZ_IPV4_HEADER + SZ_UDP_HEADER ) begin tx_data_pkt = dpr_di_reg[7:0]; // packet headers fcs_dout = dpr_di_reg[7:0]; @@ -712,13 +757,14 @@ always @(*) end else begin - tx_data_pkt = tx_fifo_d_m1[7:0]; // read data from memory + tx_data_pkt = tx_fifo_d_m1[7:0]; // read data from FIFO tx_last_byte = tx_fifo_d_m1[8]; end end TX_ST_5: begin - tx_data_pkt = 8'h0; // pad + tx_data_pkt = 8'h00; // pad + fcs_dout = 8'h00; end TX_ST_6: begin tx_data_pkt = fcs_din; // read from fcs @@ -751,7 +797,7 @@ always @(*) TX_ST_C: begin tx_data_pkt = D16_2; // 2nd idle code - tx_disp_correct = 1'b1; // PCS may convert D16.2 to a D5.6 for I2 to flip disparity + i_tx_disp_correct = 1'b1; // PCS may convert D16.2 to a D5.6 for I2 to flip disparity tx_f_pkt = 1'b1; end default: @@ -779,6 +825,8 @@ always @(*) tx_fifo_re = 1'b1; else tx_fifo_re = 1'b0; + else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_state == TX_ST_4 && tx_byte_cnt > SZ_ETH_HEADER + SZ_IPV4_HEADER + SZ_UDP_HEADER - 2) + tx_fifo_re = 1'b1; else tx_fifo_re = 1'b0; @@ -789,7 +837,7 @@ always @(posedge clk, negedge rstn) else if (tx_sample) if ( mode_100Mbit && tx_state == TX_ST_1 && tx_byte_cnt == 'h5 ) param_addr <= 'h0; - else if ( mode_1Gbit && tx_state == TX_ST_1 && tx_byte_cnt == 'h4 ) + else if ( mode_1Gbit && tx_state == TX_ST_1 && tx_byte_cnt == 'h2 ) param_addr <= 'h0; else param_addr <= param_addr + 1; @@ -858,7 +906,8 @@ always @(posedge clk or negedge rstn) assign dpr_we = 1'b0; assign dpr_ce = 1'b1; -assign dpr_ad = { 4'h0, param_addr }; +assign dpr_ad = param_addr; +assign dpr_do = 9'd0; /* * tx_sop, K27_7, 0xFB /S/ Start_of_Packet @@ -867,7 +916,7 @@ assign dpr_ad = { 4'h0, param_addr }; always @(posedge clk or negedge rstn) if (!rstn) tx_sop <=1'b0; - else if ( tx_state == TX_ST_0 && tx_mode == TX_MODE_XMT_PKT ) + else if ( tx_state == TX_ST_0 && tx_mode >= TX_MODE_XMT_PKT ) tx_sop <= 1'b1; else tx_sop <= 1'b0; @@ -883,11 +932,40 @@ always @(posedge clk or negedge rstn) else tx_eop <= 1'b0; +// Layer 3 TX Support +always @(posedge clk or negedge rstn) + if (!rstn) + tx_ipv4_length <= 16'h0000; + else if ( tx_state == TX_ST_1 ) + tx_ipv4_length <= {5'h00, tx_byte_cnt_i} +SZ_IPV4_HEADER + SZ_UDP_HEADER; + +// tx_ipv4_cksum +always @(posedge clk or negedge rstn) + if (!rstn) + tx_ipv4_cksum <= 18'h00000; + else if ( tx_state == TX_ST_2 ) + tx_ipv4_cksum <= {10'h000, dpr_di_reg[7:0]}; + else if ( tx_state == TX_ST_3 ) + tx_ipv4_cksum <= {2'b00, dpr_di_reg[7:0], tx_ipv4_cksum[7:0]}; + else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd1) + tx_ipv4_cksum <= tx_ipv4_cksum + tx_ipv4_length; + else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd2) + tx_ipv4_cksum <= {2'b00,tx_ipv4_cksum[15:0]} + {16'h0000,tx_ipv4_cksum[17:16]}; + else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd3) + tx_ipv4_cksum <= {2'b00, ~tx_ipv4_cksum[15:0]}; + +// Layer 4 TX Support +always @(posedge clk or negedge rstn) + if (!rstn) + tx_udp_length <= 16'h0000; + else if ( tx_state == TX_ST_1 ) + tx_udp_length <= {5'h00, tx_byte_cnt_i} + SZ_UDP_HEADER; + /* Debug TX */ always @(posedge clk or negedge rstn) if (!rstn) tx_active <=1'b0; - else if ( tx_state != 0 ) + else if ( tx_state == TX_ST_1 ) tx_active <= 1'b1; else tx_active <= 1'b0; diff --git a/source/pcs.v b/source/pcs.v deleted file mode 100644 index 8722887..0000000 --- a/source/pcs.v +++ /dev/null @@ -1,228 +0,0 @@ -/* synthesis translate_off*/ -`define SBP_SIMULATION -/* synthesis translate_on*/ -`ifndef SBP_SIMULATION -`define SBP_SYNTHESIS -`endif - -// -// Verific Verilog Description of module pcs -// -module pcs (sgmii0_rx_cv_err, sgmii0_rx_disp_err, sgmii0_rx_k, sgmii0_rxdata, - sgmii0_sci_addr, sgmii0_sci_rddata, sgmii0_sci_wrdata, sgmii0_tx_disp_correct, - sgmii0_tx_k, sgmii0_txdata, sgmii0_xmit, sgmii1_rx_cv_err, - sgmii1_rx_disp_err, sgmii1_rx_k, sgmii1_rxdata, sgmii1_tx_disp_correct, - sgmii1_tx_k, sgmii1_txdata, sgmii1_xmit, sgmii2_rx_cv_err, - sgmii2_rx_disp_err, sgmii2_rx_k, sgmii2_rxdata, sgmii2_sci_addr, - sgmii2_sci_rddata, sgmii2_sci_wrdata, sgmii2_tx_disp_correct, - sgmii2_tx_k, sgmii2_txdata, sgmii2_xmit, refclk0_refclkn, - refclk0_refclkp, sgmii0_ctc_del_s, sgmii0_ctc_ins_s, sgmii0_ctc_orun_s, - sgmii0_ctc_urun_s, sgmii0_cyawstn, sgmii0_hdinn, sgmii0_hdinp, - sgmii0_hdoutn, sgmii0_hdoutp, sgmii0_lsm_status_s, sgmii0_rst_dual_c, - sgmii0_rx_cdr_lol_s, sgmii0_rx_los_low_s, sgmii0_rx_pcs_rst_c, - sgmii0_rx_pwrup_c, sgmii0_rx_serdes_rst_c, sgmii0_sci_en, - sgmii0_sci_en_dual, sgmii0_sci_int, sgmii0_sci_rd, sgmii0_sci_sel, - sgmii0_sci_sel_dual, sgmii0_sci_wrn, sgmii0_serdes_rst_dual_c, - sgmii0_signal_detect_c, sgmii0_tx_pclk, sgmii0_tx_pcs_rst_c, - sgmii0_tx_pwrup_c, sgmii0_tx_serdes_rst_c, sgmii0_txi_clk, sgmii0_pll_lol, - sgmii1_ctc_del_s, sgmii1_ctc_ins_s, sgmii1_ctc_orun_s, sgmii1_ctc_urun_s, - sgmii1_hdinn, sgmii1_hdinp, sgmii1_hdoutn, sgmii1_hdoutp, - sgmii1_lsm_status_s, sgmii1_rst_dual_c, - sgmii1_rx_cdr_lol_s, sgmii1_rx_los_low_s, sgmii1_rx_pcs_rst_c, - sgmii1_rx_pwrup_c, sgmii1_rx_serdes_rst_c, - sgmii1_serdes_pdb, sgmii1_serdes_rst_dual_c, sgmii1_signal_detect_c, - sgmii1_tx_pclk, sgmii1_tx_pcs_rst_c, sgmii1_tx_pwrup_c, sgmii1_tx_serdes_rst_c, - sgmii1_txi_clk, sgmii2_ctc_del_s, sgmii2_ctc_ins_s, sgmii2_ctc_orun_s, - sgmii2_ctc_urun_s, sgmii2_cyawstn, sgmii2_hdinn, sgmii2_hdinp, - sgmii2_hdoutn, sgmii2_hdoutp, sgmii2_lsm_status_s, sgmii2_pll_lol, - sgmii2_rst_dual_c, sgmii2_rx_cdr_lol_s, sgmii2_rx_los_low_s, - sgmii2_rx_pcs_rst_c, sgmii2_rx_pwrup_c, sgmii2_rx_serdes_rst_c, - sgmii2_sci_en, sgmii2_sci_en_dual, sgmii2_sci_int, sgmii2_sci_rd, - sgmii2_sci_sel, sgmii2_sci_sel_dual, sgmii2_sci_wrn, sgmii2_serdes_pdb, - sgmii2_serdes_rst_dual_c, sgmii2_signal_detect_c, sgmii2_tx_pclk, - sgmii2_tx_pcs_rst_c, sgmii2_tx_pwrup_c, sgmii2_tx_serdes_rst_c, - sgmii2_txi_clk, refclk0_refclko) /* synthesis sbp_module=true */ ; - output [0:0]sgmii0_rx_cv_err; - output [0:0]sgmii0_rx_disp_err; - output [0:0]sgmii0_rx_k; - output [7:0]sgmii0_rxdata; - input [5:0]sgmii0_sci_addr; - output [7:0]sgmii0_sci_rddata; - input [7:0]sgmii0_sci_wrdata; - input [0:0]sgmii0_tx_disp_correct; - input [0:0]sgmii0_tx_k; - input [7:0]sgmii0_txdata; - input [0:0]sgmii0_xmit; - output [0:0]sgmii1_rx_cv_err; - output [0:0]sgmii1_rx_disp_err; - output [0:0]sgmii1_rx_k; - output [7:0]sgmii1_rxdata; - input [0:0]sgmii1_tx_disp_correct; - input [0:0]sgmii1_tx_k; - input [7:0]sgmii1_txdata; - input [0:0]sgmii1_xmit; - output [0:0]sgmii2_rx_cv_err; - output [0:0]sgmii2_rx_disp_err; - output [0:0]sgmii2_rx_k; - output [7:0]sgmii2_rxdata; - input [5:0]sgmii2_sci_addr; - output [7:0]sgmii2_sci_rddata; - input [7:0]sgmii2_sci_wrdata; - input [0:0]sgmii2_tx_disp_correct; - input [0:0]sgmii2_tx_k; - input [7:0]sgmii2_txdata; - input [0:0]sgmii2_xmit; - input refclk0_refclkn; - input refclk0_refclkp; - output sgmii0_ctc_del_s; - output sgmii0_ctc_ins_s; - output sgmii0_ctc_orun_s; - output sgmii0_ctc_urun_s; - input sgmii0_cyawstn; - input sgmii0_hdinn; - input sgmii0_hdinp; - output sgmii0_hdoutn; - output sgmii0_hdoutp; - output sgmii0_lsm_status_s; - input sgmii0_rst_dual_c; - output sgmii0_rx_cdr_lol_s; - output sgmii0_rx_los_low_s; - input sgmii0_rx_pcs_rst_c; - input sgmii0_rx_pwrup_c; - input sgmii0_rx_serdes_rst_c; - input sgmii0_sci_en; - input sgmii0_sci_en_dual; - output sgmii0_sci_int; - input sgmii0_sci_rd; - input sgmii0_sci_sel; - input sgmii0_sci_sel_dual; - input sgmii0_sci_wrn; - input sgmii0_serdes_rst_dual_c; - input sgmii0_signal_detect_c; - output sgmii0_tx_pclk; - input sgmii0_tx_pcs_rst_c; - input sgmii0_tx_pwrup_c; - input sgmii0_tx_serdes_rst_c; - input sgmii0_txi_clk; - output sgmii0_pll_lol; - output sgmii1_ctc_del_s; - output sgmii1_ctc_ins_s; - output sgmii1_ctc_orun_s; - output sgmii1_ctc_urun_s; - input sgmii1_hdinn; - input sgmii1_hdinp; - output sgmii1_hdoutn; - output sgmii1_hdoutp; - output sgmii1_lsm_status_s; - input sgmii1_rst_dual_c; - output sgmii1_rx_cdr_lol_s; - output sgmii1_rx_los_low_s; - input sgmii1_rx_pcs_rst_c; - input sgmii1_rx_pwrup_c; - input sgmii1_rx_serdes_rst_c; - input sgmii1_serdes_pdb; - input sgmii1_serdes_rst_dual_c; - input sgmii1_signal_detect_c; - output sgmii1_tx_pclk; - input sgmii1_tx_pcs_rst_c; - input sgmii1_tx_pwrup_c; - input sgmii1_tx_serdes_rst_c; - input sgmii1_txi_clk; - output sgmii2_ctc_del_s; - output sgmii2_ctc_ins_s; - output sgmii2_ctc_orun_s; - output sgmii2_ctc_urun_s; - input sgmii2_cyawstn; - input sgmii2_hdinn; - input sgmii2_hdinp; - output sgmii2_hdoutn; - output sgmii2_hdoutp; - output sgmii2_lsm_status_s; - output sgmii2_pll_lol; - input sgmii2_rst_dual_c; - output sgmii2_rx_cdr_lol_s; - output sgmii2_rx_los_low_s; - input sgmii2_rx_pcs_rst_c; - input sgmii2_rx_pwrup_c; - input sgmii2_rx_serdes_rst_c; - input sgmii2_sci_en; - input sgmii2_sci_en_dual; - output sgmii2_sci_int; - input sgmii2_sci_rd; - input sgmii2_sci_sel; - input sgmii2_sci_sel_dual; - input sgmii2_sci_wrn; - input sgmii2_serdes_pdb; - input sgmii2_serdes_rst_dual_c; - input sgmii2_signal_detect_c; - output sgmii2_tx_pclk; - input sgmii2_tx_pcs_rst_c; - input sgmii2_tx_pwrup_c; - input sgmii2_tx_serdes_rst_c; - input sgmii2_txi_clk; - output refclk0_refclko; - - - wire sli_rst_wire0, sli_rst_wire2; - - assign sli_rst_wire0 = sgmii0_serdes_rst_dual_c || sgmii0_tx_serdes_rst_c || (!sgmii1_serdes_pdb) || (!sgmii0_tx_pwrup_c) || (!sgmii1_tx_pwrup_c); - assign sli_rst_wire2 = sgmii2_serdes_rst_dual_c || sgmii2_tx_serdes_rst_c || (!sgmii2_serdes_pdb) || (!sgmii2_tx_pwrup_c); - refclk0 refclk0_inst (.refclkn(refclk0_refclkn), .refclko(refclk0_refclko), - .refclkp(refclk0_refclkp)); - sgmii0 sgmii0_inst (.rx_cv_err({sgmii0_rx_cv_err}), .rx_disp_err({sgmii0_rx_disp_err}), - .rx_k({sgmii0_rx_k}), .rxdata({sgmii0_rxdata}), .sci_addr({sgmii0_sci_addr}), - .sci_rddata({sgmii0_sci_rddata}), .sci_wrdata({sgmii0_sci_wrdata}), - .tx_disp_correct({sgmii0_tx_disp_correct}), .tx_k({sgmii0_tx_k}), - .txdata({sgmii0_txdata}), .xmit({sgmii0_xmit}), .ctc_del_s(sgmii0_ctc_del_s), - .ctc_ins_s(sgmii0_ctc_ins_s), .ctc_orun_s(sgmii0_ctc_orun_s), - .ctc_urun_s(sgmii0_ctc_urun_s), .cyawstn(sgmii0_cyawstn), .hdinn(sgmii0_hdinn), - .hdinp(sgmii0_hdinp), .hdoutn(sgmii0_hdoutn), .hdoutp(sgmii0_hdoutp), - .lsm_status_s(sgmii0_lsm_status_s), .pll_refclki(refclk0_refclko), - .rst_dual_c(sgmii0_rst_dual_c), .rx_cdr_lol_s(sgmii0_rx_cdr_lol_s), - .rx_los_low_s(sgmii0_rx_los_low_s), .rx_pcs_rst_c(sgmii0_rx_pcs_rst_c), - .rx_pwrup_c(sgmii0_rx_pwrup_c), .rx_serdes_rst_c(sgmii0_rx_serdes_rst_c), - .rxrefclk(refclk0_refclko), .sci_en(sgmii0_sci_en), .sci_en_dual(sgmii0_sci_en_dual), - .sci_int(sgmii0_sci_int), .sci_rd(sgmii0_sci_rd), .sci_sel(sgmii0_sci_sel), - .sci_sel_dual(sgmii0_sci_sel_dual), .sci_wrn(sgmii0_sci_wrn), - .serdes_pdb(sgmii1_serdes_pdb), .serdes_rst_dual_c(sgmii0_serdes_rst_dual_c), - .signal_detect_c(sgmii0_signal_detect_c), .sli_rst(sli_rst_wire0), - .tx_pclk(sgmii0_tx_pclk), .tx_pcs_rst_c(sgmii0_tx_pcs_rst_c), - .tx_pwrup_c(sgmii0_tx_pwrup_c), .tx_serdes_rst_c(sgmii0_tx_serdes_rst_c), - .txi_clk(sgmii0_txi_clk), .pll_lol(sgmii0_pll_lol)); - sgmii1 sgmii1_inst (.rx_cv_err({sgmii1_rx_cv_err}), .rx_disp_err({sgmii1_rx_disp_err}), - .rx_k({sgmii1_rx_k}), .rxdata({sgmii1_rxdata}), .tx_disp_correct({sgmii1_tx_disp_correct}), - .tx_k({sgmii1_tx_k}), .txdata({sgmii1_txdata}), .xmit({sgmii1_xmit}), - .ctc_del_s(sgmii1_ctc_del_s), .ctc_ins_s(sgmii1_ctc_ins_s), .ctc_orun_s(sgmii1_ctc_orun_s), - .ctc_urun_s(sgmii1_ctc_urun_s), .hdinn(sgmii1_hdinn), .hdinp(sgmii1_hdinp), - .hdoutn(sgmii1_hdoutn), .hdoutp(sgmii1_hdoutp), .lsm_status_s(sgmii1_lsm_status_s), - .pll_refclki(refclk0_refclko), .rst_dual_c(sgmii1_rst_dual_c), - .rx_cdr_lol_s(sgmii1_rx_cdr_lol_s), .rx_los_low_s(sgmii1_rx_los_low_s), - .rx_pcs_rst_c(sgmii1_rx_pcs_rst_c), .rx_pwrup_c(sgmii1_rx_pwrup_c), - .rx_serdes_rst_c(sgmii1_rx_serdes_rst_c), .rxrefclk(refclk0_refclko), - .serdes_pdb(sgmii1_serdes_pdb), .serdes_rst_dual_c(sgmii1_serdes_rst_dual_c), - .signal_detect_c(sgmii1_signal_detect_c), .tx_pclk(sgmii1_tx_pclk), - .tx_pcs_rst_c(sgmii1_tx_pcs_rst_c), .tx_pwrup_c(sgmii1_tx_pwrup_c), - .tx_serdes_rst_c(sgmii1_tx_serdes_rst_c), .txi_clk(sgmii1_txi_clk)); - sgmii2 sgmii2_inst (.rx_cv_err({sgmii2_rx_cv_err}), .rx_disp_err({sgmii2_rx_disp_err}), - .rx_k({sgmii2_rx_k}), .rxdata({sgmii2_rxdata}), .sci_addr({sgmii2_sci_addr}), - .sci_rddata({sgmii2_sci_rddata}), .sci_wrdata({sgmii2_sci_wrdata}), - .tx_disp_correct({sgmii2_tx_disp_correct}), .tx_k({sgmii2_tx_k}), - .txdata({sgmii2_txdata}), .xmit({sgmii2_xmit}), .ctc_del_s(sgmii2_ctc_del_s), - .ctc_ins_s(sgmii2_ctc_ins_s), .ctc_orun_s(sgmii2_ctc_orun_s), - .ctc_urun_s(sgmii2_ctc_urun_s), .cyawstn(sgmii2_cyawstn), .hdinn(sgmii2_hdinn), - .hdinp(sgmii2_hdinp), .hdoutn(sgmii2_hdoutn), .hdoutp(sgmii2_hdoutp), - .lsm_status_s(sgmii2_lsm_status_s), .pll_lol(sgmii2_pll_lol), - .pll_refclki(refclk0_refclko), .rst_dual_c(sgmii2_rst_dual_c), - .rx_cdr_lol_s(sgmii2_rx_cdr_lol_s), .rx_los_low_s(sgmii2_rx_los_low_s), - .rx_pcs_rst_c(sgmii2_rx_pcs_rst_c), .rx_pwrup_c(sgmii2_rx_pwrup_c), - .rx_serdes_rst_c(sgmii2_rx_serdes_rst_c), .rxrefclk(refclk0_refclko), - .sci_en(sgmii2_sci_en), .sci_en_dual(sgmii2_sci_en_dual), .sci_int(sgmii2_sci_int), - .sci_rd(sgmii2_sci_rd), .sci_sel(sgmii2_sci_sel), .sci_sel_dual(sgmii2_sci_sel_dual), - .sci_wrn(sgmii2_sci_wrn), .serdes_pdb(sgmii2_serdes_pdb), .serdes_rst_dual_c(sgmii2_serdes_rst_dual_c), - .signal_detect_c(sgmii2_signal_detect_c), .sli_rst(sli_rst_wire2), - .tx_pclk(sgmii2_tx_pclk), .tx_pcs_rst_c(sgmii2_tx_pcs_rst_c), - .tx_pwrup_c(sgmii2_tx_pwrup_c), .tx_serdes_rst_c(sgmii2_tx_serdes_rst_c), - .txi_clk(sgmii2_txi_clk)); - -endmodule - diff --git a/source/pkt_filter.v b/source/pkt_filter.v index e632d32..9140c74 100644 --- a/source/pkt_filter.v +++ b/source/pkt_filter.v @@ -1,7 +1,7 @@ /* * pkt_filter.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. @@ -48,7 +48,8 @@ module pkt_filter #(parameter DEPTH = 4, output reg keep ); -reg trigger_m1; +reg trigger_m1; +wire match; /* trigger_m1 is used to sync the CAM search with testing the results below */ @@ -91,3 +92,4 @@ cam #(.DEPTH(DEPTH), .DEPTHW(DEPTHW), .WIDTH(WIDTH)) cam_0( endmodule + diff --git a/source/sgmii_params.v b/source/sgmii_params.v index 70cb1f1..a36160e 100644 --- a/source/sgmii_params.v +++ b/source/sgmii_params.v @@ -1,7 +1,7 @@ /* * sgmii_params.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. @@ -28,7 +28,6 @@ localparam SGMII_SPEED_10MBIT = 2'b00, SGMII_SPEED_RSVD = 2'b11, SGMII_SPEED_AN = 2'b11; - /* * Notes about K Codes: * Start of Packet: /S/, K27.7, 0xFB @@ -45,6 +44,12 @@ localparam D2_2 = 8'h42, /* Note that these are only K codes if the k bit is asserted */ K23_7 = 8'hf7, // /R/ Carrier Extend K27_7 = 8'hfb, // /S/ Start_of_Packet + K28_0 = 8'h1c, + K28_1 = 8'h3c, + K28_2 = 8'h5c, + K28_3 = 8'h7c, + K28_4 = 8'h9c, K28_5 = 8'hbc, + K28_6 = 8'hdc, K29_7 = 8'hfd, // /T/ End_of_Packet K_ERROR = 8'hee; diff --git a/source/spi.v b/source/spi.v index 7d6004e..d7c054b 100644 --- a/source/spi.v +++ b/source/spi.v @@ -1,7 +1,7 @@ /* * spi.v * - * Copyright (C) 2018, 2019 Mind Chasers Inc. + * Copyright (C) 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. @@ -18,8 +18,7 @@ * function: SPI slave controller * * refer to SPI protocol figure at https://mindchasers.com/dev/hw-spi - * - * + * */ `timescale 1ns /10ps @@ -72,7 +71,8 @@ wire bit_cnt_rstn; // async reset at start of SPI cycle reg spi_clk_m1, spi_clk_m2; // detect / debounce the SPI CLK - reg spi_clk_high, spi_clk_high_m1; // one shot clocks for sequencing events + reg spi_clk_high, spi_clk_high_m1; // one shot clocks for sequencing events + reg spi_clk_low, spi_clk_low_m1; // one shot clocks for sequencing events reg [4:0] bit_cnt; // cnt the bits reg [6:0] word_cnt; // number of bytes transferred, OK to roll over @@ -119,6 +119,25 @@ spi_clk_high_m1 <= spi_clk_high; end + + // create two seq one shots for actions + always @(posedge clk or negedge bit_cnt_rstn) + begin + if ( !bit_cnt_rstn ) + spi_clk_low <= 0; + else if ( spi_cs && spi_clk && !spi_clk_m1 && spi_clk_m2 ) + spi_clk_low <= 1'b1; + else + spi_clk_low <= 1'b0; + end + + always @(posedge clk or negedge bit_cnt_rstn) + begin + if ( !bit_cnt_rstn ) + spi_clk_low_m1 <= 0; + else + spi_clk_low_m1 <= spi_clk_low; + end /* bit_cnt indicates the state of the SPI transfer @@ -132,7 +151,7 @@ begin if ( !bit_cnt_rstn ) bit_cnt <= 5'h0; - else if ( spi_cs && spi_clk_high ) begin + else if ( spi_cs && spi_clk_high_m1 ) begin if ( bit_cnt == 5'd26 ) bit_cnt <= 5'd18; else @@ -198,44 +217,40 @@ // we always @(posedge clk or negedge bit_cnt_rstn) - begin if (!bit_cnt_rstn) we <= 1'b0; - else if ( spi_cs ) begin - if ( spi_clk_high && !rwn && bit_cnt == 5'd25 ) + else if ( spi_cs ) + if ( spi_clk_high && !rwn && bit_cnt == 5'd26 ) we <= 1'b1; else we <= 1'b0; - end; - end /* SPI data output enable */ assign spi_d_oe = spi_cs; /* - * clock out msb first. - * First bit comes out on cs + * clock out msb first. + * */ always @(posedge clk or negedge bit_cnt_rstn) - begin if ( !bit_cnt_rstn ) spi_d_o <= start_code[8]; else if ( spi_cs && spi_clk_high_m1 ) begin if ( bit_cnt < 9 ) spi_d_o <= start_code['d8 - bit_cnt[3:0]]; - else if ( !rwn && bit_cnt >= 'd18 ) - spi_d_o <= word_cnt['d8 - bit_cnt[3:0]]; - else if ( rwn && bit_cnt >= 'd18 ) - spi_d_o <= d_i['d8 - bit_cnt[3:0]]; - else + else if ( !rwn && bit_cnt >= 'd18 && bit_cnt < 'd26 ) + spi_d_o <= word_cnt['d25-bit_cnt]; + else if ( rwn && bit_cnt >= 'd18 && bit_cnt < 'd26 ) + spi_d_o <= d_i['d25-bit_cnt]; + else spi_d_o <= 1'b0; end - end - - assign oe = ( (dpram_rx_sel || dpram_tx_sel) && rwn) ? 1'b1 : 1'b0; - - + else if (spi_cs && spi_clk_high_m1 && rwn && bit_cnt == 'd26) + spi_d_o <= d_i[8]; + + assign oe = mem_sel && rwn; + /* Address Decoding */ assign pkt_filter_sel = pkt_filter_sel_01 | pkt_filter_sel_02 | pkt_filter_sel_10 | pkt_filter_sel_12 | pkt_filter_sel_20 | pkt_filter_sel_21 | pkt_filter_sel_23; @@ -297,4 +312,4 @@ end endmodule - +
\ No newline at end of file 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; diff --git a/source/sync2_fifo.v b/source/sync2_fifo.v deleted file mode 100644 index 029cfce..0000000 --- a/source/sync2_fifo.v +++ /dev/null @@ -1,141 +0,0 @@ -/* - * sync2_fifo.v - * - * Copyright (C) 2018, 2019 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: Multi Buffered Sync FIFO suitable for rate conversion from 1G to 100 Mbit - * - * - */ - - -`timescale 1ns /10ps - -module sync2_fifo #(parameter FIFO_PTR = 12, - FIFO_WIDTH = 9, - FIFO_DEPTH = 4096 ) -( - input rstn, - input clk, - - - // input - input we, - input [FIFO_WIDTH-1:0] d_in, - - // output - input re, - output [FIFO_WIDTH-1:0] d_out, - output empty, - output almost_full, - - // fifo_control - input reset_ptrs - -); - -`include "ethernet_params.v" - - -reg [FIFO_PTR-1:0] wr_ptr; -reg [FIFO_PTR-1:0] rd_ptr; -reg [FIFO_PTR:0] bytes; // use for size calculation below - -wire [FIFO_WIDTH-1:0] d_out_0, d_out_1, d_out_internal; - -wire dpram0_a_clk_e, dpram1_a_clk_e; -wire dpram0_b_clk_e, dpram1_b_clk_e; - - -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_ptr <= 'd0; - else if ( reset_ptrs ) - wr_ptr <= 'd0; - else if ( we ) - wr_ptr <= wr_ptr + 1; - -/* - * rd_ptr - * use empty flat to make sure rd_ptr doesn't advance when empty ( error condition ) - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - rd_ptr <= 'd0; - else if ( reset_ptrs ) - rd_ptr <= 'd0; - else if ( re && !empty ) - rd_ptr <= rd_ptr + 1; - -assign empty = ( rd_ptr == wr_ptr ) ? 1'b1 : 1'b0; - -// leave room for a MTU frame -assign almost_full = bytes > FIFO_DEPTH-MTU ? 1'b1 : 1'b0; - -always @(posedge clk, negedge rstn) - if( !rstn ) - bytes <= 'd0; - else if ( wr_ptr >= rd_ptr ) - bytes <= wr_ptr - rd_ptr; - else - bytes <= (wr_ptr - rd_ptr)+FIFO_DEPTH; - - assign dpram0_a_clk_e = ~wr_ptr[FIFO_PTR-1]; - assign dpram1_a_clk_e = wr_ptr[FIFO_PTR-1]; - - assign dpram0_b_clk_e = ~rd_ptr[FIFO_PTR-1]; - assign dpram1_b_clk_e = rd_ptr[FIFO_PTR-1]; - - assign d_out = dpram0_b_clk_e ? d_out_0 : d_out_1; - -dpram dpram_fifo0( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( dpram0_a_clk_e ), - .a_we( we ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr[10:0] ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( dpram0_b_clk_e ), - .b_we( 1'b0 ), - .b_oe( 1'b1 ), - .b_addr( rd_ptr[10:0] ), - .b_din( 9'h0 ), - .b_dout( d_out_0 ) -); - -dpram dpram_fifo1( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( dpram1_a_clk_e ), - .a_we( we ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr[10:0] ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( dpram1_b_clk_e ), - .b_we( 1'b0 ), - .b_oe( 1'b1 ), - .b_addr( rd_ptr[10:0] ), - .b_din( 9'h0 ), - .b_dout( d_out_1 ) - ); - -endmodule diff --git a/source/sync4_fifo.v b/source/sync4_fifo.v deleted file mode 100644 index c7c1fb6..0000000 --- a/source/sync4_fifo.v +++ /dev/null @@ -1,206 +0,0 @@ -/* - * sync4_fifo.v - * - * Copyright (C) 2018, 2019 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: FIFO / data store between RX and TX for each path - * - */ - -`timescale 1ns /10ps - -module sync4_fifo #(parameter FIFO_PTR = 13, - FIFO_WIDTH = 9, - FIFO_DEPTH = 8192 ) -( - input rstn, - input clk, - - // input - input we, - input [FIFO_WIDTH-1:0] d_in, - - // output - input re, - output reg [FIFO_WIDTH-1:0] d_out, - output empty, - output almost_full, - - // fifo_control - input reset_ptrs, - - // debug - output active - -); - -`include "ethernet_params.v" - -reg [FIFO_PTR-1:0] wr_ptr; -reg [FIFO_PTR-1:0] rd_ptr; -reg [FIFO_PTR-1:0] wr_bytes_available; // use for size calculation below - -wire [FIFO_WIDTH-1:0] d_out_0, d_out_1, d_out_2, d_out_3; - -wire dpram0_a_clk_e, dpram1_a_clk_e, dpram2_a_clk_e, dpram3_a_clk_e; -wire dpram0_b_clk_e, dpram1_b_clk_e, dpram2_b_clk_e, dpram3_b_clk_e; -reg dpram0_b_clk_e_m1, dpram1_b_clk_e_m1, dpram2_b_clk_e_m1, dpram3_b_clk_e_m1; - - -always @(posedge clk, negedge rstn) - if( !rstn ) begin - dpram0_b_clk_e_m1 <= 1'b0; - dpram1_b_clk_e_m1 <= 1'b0; - dpram2_b_clk_e_m1 <= 1'b0; - dpram3_b_clk_e_m1 <= 1'b0; - end - else begin - dpram0_b_clk_e_m1 <= dpram0_b_clk_e; - dpram1_b_clk_e_m1 <= dpram1_b_clk_e; - dpram2_b_clk_e_m1 <= dpram2_b_clk_e; - dpram3_b_clk_e_m1 <= dpram3_b_clk_e; - end - -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_ptr <= 'd0; - else if ( reset_ptrs ) - wr_ptr <= 'd0; - else if ( we ) - wr_ptr <= wr_ptr + 1; - -/* - * rd_ptr - * use empty flag to make sure rd_ptr doesn't advance when empty ( error condition ) - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - rd_ptr <= 'd0; - else if ( reset_ptrs ) - rd_ptr <= 'd0; - else if ( re && !empty ) - rd_ptr <= rd_ptr + 1; - -assign empty = ( rd_ptr == wr_ptr ) ? 1'b1 : 1'b0; -assign almost_full = wr_bytes_available < MTU ? 1'b1 : 1'b0; - -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_bytes_available <= FIFO_DEPTH-1; - else if ( wr_ptr >= rd_ptr ) - wr_bytes_available <= FIFO_DEPTH-1 - (wr_ptr - rd_ptr); - else - wr_bytes_available <= rd_ptr - wr_ptr; - -assign dpram0_a_clk_e = wr_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b00 ? 1'b1 : 1'b0; -assign dpram1_a_clk_e = wr_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b01 ? 1'b1 : 1'b0; -assign dpram2_a_clk_e = wr_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b10 ? 1'b1 : 1'b0; -assign dpram3_a_clk_e = wr_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b11 ? 1'b1 : 1'b0; - -assign dpram0_b_clk_e = rd_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b00 ? 1'b1 : 1'b0; -assign dpram1_b_clk_e = rd_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b01 ? 1'b1 : 1'b0; -assign dpram2_b_clk_e = rd_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b10 ? 1'b1 : 1'b0; -assign dpram3_b_clk_e = rd_ptr[FIFO_PTR-1:FIFO_PTR-2] == 2'b11 ? 1'b1 : 1'b0; - -// we have to delay the mux one bit for when the DPRAM switches. Otherwise, we read from the wrong DPRAM for one time slot -always @(*) - if (dpram0_b_clk_e_m1) - d_out = d_out_0; - else if (dpram1_b_clk_e_m1) - d_out = d_out_1; - else if (dpram2_b_clk_e_m1) - d_out = d_out_2; - else if (dpram3_b_clk_e_m1) - d_out = d_out_3; - -assign active = ~empty; - -dpram dpram_fifo0( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( dpram0_a_clk_e ), - .a_we( we ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr[10:0] ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( dpram0_b_clk_e ), - .b_we( 1'b0 ), - .b_oe( 1'b1 ), - .b_addr( rd_ptr[10:0] ), - .b_din( 9'h0 ), - .b_dout( d_out_0 ) -); - -dpram dpram_fifo1( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( dpram1_a_clk_e ), - .a_we( we ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr[10:0] ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( dpram1_b_clk_e ), - .b_we( 1'b0 ), - .b_oe( 1'b1 ), - .b_addr( rd_ptr[10:0] ), - .b_din( 9'h0 ), - .b_dout( d_out_1 ) - ); - -dpram dpram_fifo2( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( dpram2_a_clk_e ), - .a_we( we ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr[10:0] ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( dpram2_b_clk_e ), - .b_we( 1'b0 ), - .b_oe( 1'b1 ), - .b_addr( rd_ptr[10:0] ), - .b_din( 9'h0 ), - .b_dout( d_out_2 ) - ); - -dpram dpram_fifo3( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( dpram3_a_clk_e ), - .a_we( we ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr[10:0] ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( dpram3_b_clk_e ), - .b_we( 1'b0 ), - .b_oe( 1'b1 ), - .b_addr( rd_ptr[10:0] ), - .b_din( 9'h0 ), - .b_dout( d_out_3 ) - ); - -endmodule diff --git a/source/top.v b/source/top.v deleted file mode 100644 index 3913163..0000000 --- a/source/top.v +++ /dev/null @@ -1,2177 +0,0 @@ -/* - * top.v - * - * Copyright (C) 2018, 2019 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. - * - */ - -`timescale 1ns /10ps - -module top( - input rstn, - - // REFCLK - input refclkp_d0, refclkn_d0, - input refclkp_d1, refclkn_d1, - - // PHY Control - output phy0_resetn, - - output phy1_resetn, - - output phy2_resetn, - - // SGMII0 - input sgmii0_hdinp, - input sgmii0_hdinn, - output sgmii0_hdoutp, - output sgmii0_hdoutn, - - // SGMII1 - input sgmii1_hdinp, - input sgmii1_hdinn, - output sgmii1_hdoutp, - output sgmii1_hdoutn, - - // SGMII2 - input sgmii2_hdinp, - input sgmii2_hdinn, - output sgmii2_hdoutp, - output sgmii2_hdoutn, - - // SGMII3 - input sgmii3_hdinp, - input sgmii3_hdinn, - output sgmii3_hdoutp, - output sgmii3_hdoutn, - - // MDIO ( management ) - output phy_mdc, - inout phy0_mdio, - input [1:0] phy0_gpio, - - inout phy1_mdio, - input [1:0] phy1_gpio, - - output phy2_mdc, - inout phy2_mdio, - - input phy0_intn, - input phy1_intn, - - // Microcontroller SPI and bit banging - input fpga_spics, - input fpga_mclk, - output fpga_miso, - input fpga_mosi, - output fpga_int, - - // I2C - inout i2c_scl, - inout i2c_sda, - - // K02 UART - input uart_txd, - output uart_rxd, - - output fpga_jtag_e, - - // FTDI UART signals muxed with JTAG - input ftdi_tck_txd, - output ftdi_tdi_rxd, - - output [2:0] led, - - output ard_sda, - output ard_scl, - output ard_txd1, - output ard_rxd1, - output ard_txd2, - input ard_rxd2, - output ard_txd3, - input ard_rxd3, - - output pe0, - output pe1, - output pe3, - output pe4, - output pe5, - output pg5, - output ph3, - output ph4, - inout [9:0] pa - -); - -`include "sgmii_params.v" -`include "definitions.v" - - -/* PARAMS */ -localparam MDIO_ROM_ADDR_SZ = 7; - -/* nets and variables */ - -// clocks -wire clk_slow, clk_1_25, clk_10, clk_20; -wire clk_100; -wire refclko; - -// misc resets -wire [3:0] phy_resetn; // bit[0] will get pruned out for now -wire [3:0] mac_reset; - -// dcu resets -wire [1:0] pcs_rst_dual; -wire [1:0] serdes_rst_dual; -wire [1:0] tx_serdes_rst; - -// channel resets -wire [3:0] rx_pcs_rst; -wire [3:0] rx_serdes_rst; -wire [3:0] tx_pcs_rst; - -// MDIO controller and driver -wire mdio_cont_work_start, mdio_cont_work_run; -wire mdio_cont_work_done; -wire [MDIO_ROM_ADDR_SZ-1:0] mdio_routine_addr; -wire [1:0] mdio_mux_sel; -wire mdio_done, mdo_oe; -wire mdo; -reg mdi; -wire [15:0] mdio_wd; -wire [15:0] mdio_rd; -wire [4:0] mdio_reg_addr; -wire mdio_ld, mdio_run; -wire mdio_rwn; -wire bin_to_ascii_run; - -// MDIO Data block -wire [MDIO_ROM_ADDR_SZ-1:0] rom_a; -wire [7:0] rom_d; -wire [4:0] mdio_reg_addr_set; -wire [7:0] mdio_w_data_h_set, mdio_w_data_l_set; -wire [4:0] mdio_page_set; - -// I2C -wire sda_oe, scl_oe, sda_o, scl_o; -wire i2c_fifo_priority; - -wire read_fifo_we; -wire [8:0] fifo_r_d; - -// bin to ASCII -wire [15:0] bin_to_ascii_d_in; -wire [6:0] cont_rd; - -// PCS, mac -wire pcs_pclk; -wire [1:0] pll_lol; -wire sgmii_rx_k[0:3], sgmii_tx_k[0:3]; -wire sgmii_tx_disp_correct[0:3]; -wire sgmii_rx_cv_err[0:3], sgmii_rx_disp_err[0:3], sgmii_rx_cdr_lol[0:3]; -wire sgmii_lsm_status[0:3], sgmii_rx_los_low[0:3]; -wire [7:0] rx_data0, rx_data1, rx_data2, rx_data3; -wire [7:0] tx_data0, tx_data1, tx_data2, tx_data3; -wire [6:0] read_fifo_d_i; -wire [3:0] rx_sample; - -// ipv4 -wire [3:0] ipv4_pkt_start; -wire [3:0] ipv4_pkt_complete; - -reg cont_fifo_re_m1, cont_fifo_re_m2; -wire cont_fifo_empty; -wire i2c_fifo_re; -wire i2c_cont_we, i2c_cont_done; -wire i_cont_fifo_re; -wire bin_to_ascii_we, mdio_rd_we, cont_rd_we; -wire [3:0] phy_up; - -// Interrupts -wire [6:0] int_do; -wire [3:0] mac_int; -wire int_sel; - -// Common Internal Memory Bus -wire[10:0] mem_addr; -wire [8:0] mem_d_i; -reg [8:0] mem_d_o; -wire mem_we, mem_oe; -wire [4:0] mem_do_mux_sel; - -// DPRAM -wire [10:0] param_phy2_addr ; -wire [8:0] param_phy2_din, param_phy2_dout; -wire param_phy2_ce, param_phy2_we; - -wire [7:0] i2c_d_o; -wire [8:0] micro_fifo_do; -wire sys_mem_rx_ce, sys_mem_tx_ce, sys_mem_ptrs_sel; -wire [3:0] param_sel; - -// drop_fifos and filter -wire rx0_k_m1, rx0_k_m2, rx0_k_m3, rx0_k_m4; -wire [7:0] rx0_data_m1, rx0_data_m2, rx0_data_m3, rx0_data_m4; - -wire rx1_k_m1, rx1_k_m2, rx1_k_m3, rx1_k_m4; -wire [7:0] rx1_data_m1, rx1_data_m2, rx1_data_m3, rx1_data_m4; - -wire rx2_k_m1, rx2_k_m2, rx2_k_m3, rx2_k_m4; -wire [7:0] rx2_data_m1, rx2_data_m2, rx2_data_m3, rx2_data_m4; - -wire rx3_k_m1, rx3_k_m2, rx3_k_m3, rx3_k_m4; -wire [7:0] rx3_data_m1, rx3_data_m2, rx3_data_m3, rx3_data_m4; - -wire [3:0] rx_mac_keep; -wire [3:0] rx_sc_wr_done; - -// drop filter outputs -wire rx_df_fifo_we_01, rx_df_fifo_we_02, rx_df_fifo_we_03; -wire rx_df_fifo_we_10, rx_df_fifo_we_12, rx_df_fifo_we_13; -wire rx_df_fifo_we_20, rx_df_fifo_we_21, rx_df_fifo_we_23, rx_df_fifo_we_2u; -wire rx_df_fifo_we_30, rx_df_fifo_we_31, rx_df_fifo_we_32; -wire rx_df_fifo_we_u2; - -wire [8:0] rx_df_fifo_d_01, rx_df_fifo_d_02, rx_df_fifo_d_03; -wire [8:0] rx_df_fifo_d_10, rx_df_fifo_d_12, rx_df_fifo_d_13; -wire [8:0] rx_df_fifo_d_20, rx_df_fifo_d_21, rx_df_fifo_d_23, rx_df_fifo_d_2u; -wire [8:0] rx_df_fifo_d_30, rx_df_fifo_d_31, rx_df_fifo_d_32; -wire [8:0] rx_df_fifo_d_u2; - -// pkt filter -wire [3:0] trigger; -wire [3:0] rx_enet_bcast; -wire [3:0] rx_ipv4_arp; -wire rx_pf_keep_01; -wire rx_pf_keep_02; -wire rx_pf_keep_03; -wire rx_pf_keep_10; -wire rx_pf_keep_12; -wire rx_pf_keep_13; -wire rx_pf_keep_20; -wire rx_pf_keep_21; -wire rx_pf_keep_23; -wire rx_pf_keep_2u; -wire rx_pf_keep_30; -wire rx_pf_keep_31; -wire rx_pf_keep_32; -wire rx_pf_keep_u2; - -// rx_fifos -wire [3:0] rx_sc_fifo_we; -wire rx_sw_fifo_re_01, rx_sw_fifo_re_02, rx_sw_fifo_re_03; -wire rx_sf_fifo_empty_01, rx_sf_fifo_empty_02, rx_sf_fifo_empty_03; -wire rx_sw_fifo_re_10, rx_sw_fifo_re_12, rx_sw_fifo_re_13; -wire rx_sf_fifo_empty_10, rx_sf_fifo_empty_12, rx_sf_fifo_empty_13; -wire rx_sw_fifo_re_20, rx_sw_fifo_re_21, rx_sw_fifo_re_23, rx_sw_fifo_re_2u; -wire rx_sf_fifo_empty_20, rx_sf_fifo_empty_21, rx_sf_fifo_empty_23, rx_sf_fifo_empty_2u; -wire rx_sw_fifo_re_30, rx_sw_fifo_re_31, rx_sw_fifo_re_32; -wire rx_sf_fifo_empty_30, rx_sf_fifo_empty_31, rx_sf_fifo_empty_32; -wire rx_sw_fifo_re_u2, rx_uc_fifo_empty_u2; -wire [8:0] rx_sc_fifo_d0, rx_sc_fifo_d1, rx_sc_fifo_d2, rx_sc_fifo_d3; -wire [8:0] rx_sf_fifo_d_01, rx_sf_fifo_d_02, rx_sf_fifo_d_03; -wire [8:0] rx_sf_fifo_d_10, rx_sf_fifo_d_12, rx_sf_fifo_d_13; -wire [8:0] rx_sf_fifo_d_20, rx_sf_fifo_d_21, rx_sf_fifo_d_23, rx_sf_fifo_d_2u; -wire [8:0] rx_sf_fifo_d_30, rx_sf_fifo_d_31, rx_sf_fifo_d_32; -wire [8:0] rx_uc_fifo_d_u2; -wire rx_sf_almost_full_01, rx_sf_almost_full_02, rx_sf_almost_full_03; -wire rx_sf_almost_full_10, rx_sf_almost_full_12, rx_sf_almost_full_13; -wire rx_sf_almost_full_20, rx_sf_almost_full_21, rx_sf_almost_full_23; - - -// between switch and mac -wire [8:0] tx_sw_fifo_d0, tx_sw_fifo_d1, tx_sw_fifo_d2, tx_sw_fifo_d3, tx_sw_fifo_du; -wire [3:0] tx_sc_fifo_re; -wire tx_uc_fifo_re; -wire [3:0] tx_sw_fifo_empty; -wire tx_sw_fifo_we; - -wire [1:0] tx_sw_mode0, tx_sw_mode1, tx_sw_mode2, tx_sw_mode3; -wire tx_sw_modeu; -wire [3:0] tx_sc_done; - -// 100 Mbit -wire[3:0] mode_100Mbit; - -wire pkt_filter_sel_01, pkt_filter_sel_02, pkt_filter_sel_03; -wire pkt_filter_sel_10, pkt_filter_sel_12, pkt_filter_sel_13; -wire pkt_filter_sel_20, pkt_filter_sel_21, pkt_filter_sel_23, pkt_filter_sel_2u; -wire pkt_filter_sel_u2; - -// FCS -wire [1:0] fcs_addr0, fcs_addr1, fcs_addr2, fcs_addr3; -wire [7:0] fcs_din0, fcs_din1, fcs_din2, fcs_din3; -wire [7:0] fcs_dout0, fcs_dout1, fcs_dout2, fcs_dout3; -wire[3:0] fcs_init, fcs_enable; - -// half FIFO / DPRAM interface for uP -wire hfifo_we, hfifo_re; -wire [8:0] hfifo_tx_d, hfifo_rx_d; -wire hfifo_empty; -wire micro_fifo_int; -wire tx_uc_block; - -// SCI -wire[1:0] sci_sel_dual; -wire[3:0] sci_sel_ch; -wire[7:0] sci_rddata0, sci_rddata1 ; -wire[1:0] sci_int; - -// Metrics -wire tx_metrics, metrics_start; -wire [8:0] metrics_d; - -// Network Debug & Metrics -wire sample_enable; -reg [3:0] rx_active, tx_active; -wire [3:0] mac_rx_active; -wire [3:0] drop_rx0_active, drop_rx1_active, drop_rx2_active, drop_rx3_active; -wire [3:0] sync_rx0_active, sync_rx1_active, sync_rx2_active, sync_rx3_active; -wire [3:0] mac_tx_active; -wire [3:0] rx_sc_error; -wire [3:0] rx_eop, rx_sop; -wire [3:0] tx_eop, tx_sop; - - -/**************************** - * - * Logic Begins Below - * - ***************************/ - -/* Lattice requires GSR to be in top-level module and be named GSR_INST */ -GSR GSR_INST(.GSR(rstn)); -PUR PUR_INST(.PUR(1'b1)); - -assign phy_mdc = clk_10; -assign phy2_mdc = clk_10; - -assign phy0_resetn = phy_resetn[0]; -assign phy1_resetn = phy_resetn[1]; -assign phy2_resetn = phy_resetn[2]; - - -/* - * Clocks derived from the internal OSCG - */ -clk_gen clk_gen_0( - .rstn( rstn ), - .clk_10( clk_10 ), - .clk_5( ), - .clk_2_5( ), - .clk_1_25( clk_1_25 ), - .clk_slow( clk_slow ) -); - - -/* -* main controller -* -* controls worker blocks -* interfaces with uC via I2C -* -*/ -controller #(.ADDR_SZ( MDIO_ROM_ADDR_SZ ))controller_0 -( - .rstn( rstn ), - .clk( clk_10 ), - .init(1'b1), - .pulse_100ms( 1'b0 ), - // PCS status lines - .pcs_rx_error( mac_int ), - .pll_lol( pll_lol ), - // link status - .port_up( phy_up ), - // mdio_controller interface - .mdio_cont_start(mdio_cont_work_start), - .mdio_cont_done(mdio_cont_work_done), - .mdio_routine_addr( mdio_routine_addr ), - .mdio_run( mdio_run ), - // mdio_data params - .mdio_page( mdio_page_set ), - .mdio_reg_addr( mdio_reg_addr_set ), - .mdio_w_data_h( mdio_w_data_h_set ), - .mdio_w_data_l( mdio_w_data_l_set ), - // bin_to_ascii interface - .bin_to_ascii_run( bin_to_ascii_run ), - // ext_sys_fifo interface: controller to external I/F FIFO - .fifo_mux_sel( read_fifo_mux_sel ), - .fifo_we( cont_rd_we ), - .read_fifo_d_o( cont_rd ), - // i2c interface - .i2c_rx_we ( i2c_cont_we ), - .i2c_rx_done ( i2c_cont_done ), - .i2c_d_in( i2c_d_o ), - // reset and config - .pcs_rst_dual( pcs_rst_dual ), - .serdes_rst_dual( serdes_rst_dual ), - .tx_serdes_rst( tx_serdes_rst ), - .phy_resetn( phy_resetn ), - .mac_reset( mac_reset ), - .tx_pcs_rst( tx_pcs_rst ), - .rx_serdes_rst( rx_serdes_rst ), - .rx_pcs_rst( rx_pcs_rst ), - .mdio_mux_sel( mdio_mux_sel ), - .i2c_fifo_priority( i2c_fifo_priority ), - // TX custom packet - .tx_metrics( tx_metrics ) - -); - -/* - * Controls the routing of data and transmit modes - */ -switch switch_0( - .rstn( rstn ), - .clk( pcs_pclk ), - // PHY status - .phy_up( phy_up ), - .mode_100Mbit ( mode_100Mbit ), - // FIFO input data from RX FIFOs - .rx_d_01( rx_sf_fifo_d_01 ), - .rx_d_02( rx_sf_fifo_d_02 ), - .rx_d_03( rx_sf_fifo_d_03 ), - .rx_d_10( rx_sf_fifo_d_10 ), - .rx_d_12( rx_sf_fifo_d_12 ), - .rx_d_13( rx_sf_fifo_d_13 ), - .rx_d_20( rx_sf_fifo_d_20 ), - .rx_d_21( rx_sf_fifo_d_21 ), - .rx_d_23( rx_sf_fifo_d_23 ), - .rx_d_2u( rx_sf_fifo_d_2u ), - .rx_d_30( rx_sf_fifo_d_30 ), - .rx_d_31( rx_sf_fifo_d_31 ), - .rx_d_32( rx_sf_fifo_d_32 ), - .rx_d_u2( rx_uc_fifo_d_u2 ), - // RX FIFO read enables - .rx_fifo_re_01( rx_sw_fifo_re_01 ), - .rx_fifo_re_02( rx_sw_fifo_re_02 ), - .rx_fifo_re_03( rx_sw_fifo_re_03 ), - .rx_fifo_re_10( rx_sw_fifo_re_10 ), - .rx_fifo_re_12( rx_sw_fifo_re_12 ), - .rx_fifo_re_13( rx_sw_fifo_re_13 ), - .rx_fifo_re_20( rx_sw_fifo_re_20 ), - .rx_fifo_re_21( rx_sw_fifo_re_21 ), - .rx_fifo_re_23( rx_sw_fifo_re_23 ), - .rx_fifo_re_2u( rx_sw_fifo_re_2u ), - .rx_fifo_re_30( rx_sw_fifo_re_30 ), - .rx_fifo_re_31( rx_sw_fifo_re_31 ), - .rx_fifo_re_32( rx_sw_fifo_re_32 ), - .rx_fifo_re_u2( rx_sw_fifo_re_u2 ), - // RX FIFO Empty flags - .rx_fifo_empty_01( rx_sf_fifo_empty_01 ), - .rx_fifo_empty_02( rx_sf_fifo_empty_02 ), - .rx_fifo_empty_03( rx_sf_fifo_empty_03 ), - .rx_fifo_empty_10( rx_sf_fifo_empty_10 ), - .rx_fifo_empty_12( rx_sf_fifo_empty_12 ), - .rx_fifo_empty_13( rx_sf_fifo_empty_13 ), - .rx_fifo_empty_20( rx_sf_fifo_empty_20 ), - .rx_fifo_empty_21( rx_sf_fifo_empty_21 ), - .rx_fifo_empty_23( rx_sf_fifo_empty_23 ), - .rx_fifo_empty_2u( rx_sf_fifo_empty_2u ), - .rx_fifo_empty_30( rx_sf_fifo_empty_30 ), - .rx_fifo_empty_31( rx_sf_fifo_empty_31 ), - .rx_fifo_empty_32( rx_sf_fifo_empty_32 ), - .rx_fifo_empty_u2( rx_uc_fifo_empty_u2 ), - // TX FIFO output from internal muxes - .tx_d0( tx_sw_fifo_d0), - .tx_d1( tx_sw_fifo_d1 ), - .tx_d2( tx_sw_fifo_d2 ), - .tx_d3( tx_sw_fifo_d3 ), - .tx_du( tx_sw_fifo_du ), - // TX FIFO read enable inputs (need to route to RX output FIFOs) - .tx_fifo_re( tx_sc_fifo_re ), - .tx_fifo_we_u ( tx_sw_fifo_we ), - // TX FIFO Empty Flags (need to route to RX output FIFOs) - .tx_fifo_empty( tx_sw_fifo_empty ), - // TX modes for the PHYs and uc - .tx_mode0( tx_sw_mode0 ), - .tx_mode1( tx_sw_mode1 ), - .tx_mode2( tx_sw_mode2 ), - .tx_mode3( tx_sw_mode3 ), - .tx_modeu( tx_modeu ), - // TX state machine done flag - .tx_f( tx_sc_done ), - // TX custom packet - .tx_metrics ( tx_metrics ) -); - - -/* - * RX and TX controller logic tied to PCS/SGMII protocol - */ -mac mac_0( - .rstn( ~mac_reset[0] ), - .phy_resetn ( phy_resetn[0] ), - .clk( pcs_pclk ), - .tap_port ( 1'b0 ), - // SGMII AN - .link_timer( 1'b0 ), - .fixed_speed(SGMII_SPEED_AN), - .an_disable( 1'b0 ), - .an_link_up( ), - .an_duplex( ), - .mode_100Mbit( mode_100Mbit[0] ), - .phy_up( phy_up[0] ), - // Switch I/F - .tx_mode( tx_sw_mode0 ), - .tx_f( tx_sc_done[0] ), - // PCS / SERDES health - .rx_lsm( sgmii_lsm_status[0] ), - .rx_cv_err ( sgmii_rx_cv_err[0] ), - .rx_disp_err( sgmii_rx_disp_err[0] ), - .rx_cdr_lol( sgmii_rx_cdr_lol[0] ), - .rx_los ( sgmii_rx_los_low[0] ), - // PCS data I/F - .rx_k( sgmii_rx_k[0] ), - .rx_data( rx_data0 ), - .tx_k( sgmii_tx_k[0] ), - .tx_data( tx_data0 ), - .tx_disp_correct( sgmii_tx_disp_correct[0] ), - // Flags and Interrupts - .keep( rx_mac_keep[0] ), - // TX FCS - .fcs_init( fcs_init[0] ), - .fcs_enable( fcs_enable[0] ), - .fcs_addr( fcs_addr0 ), - .fcs_dout( fcs_din0 ), - .fcs_din( fcs_dout0 ), - // SGMII RX / FIFO Write - .rx_fifo_we( rx_sc_fifo_we[0] ), - .rx_fifo_d( rx_sc_fifo_d0 ), - .rx_error( rx_sc_error[0] ), - .rx_wr_done( rx_sc_wr_done[0] ), - // SGMII TX / FIFO Read - .tx_fifo_re( tx_sc_fifo_re[0] ), - .tx_fifo_d( tx_sw_fifo_d0 ), - .tx_fifo_empty( tx_sw_fifo_empty[0] ), - // Packet Filter - .rx_sample( rx_sample[0] ), - .ipv4_pkt_start( ipv4_pkt_start[0] ), - .trigger( ), - .rx_enet_bcast( rx_enet_bcast[0] ), - .rx_ipv4_arp( rx_ipv4_arp[0] ), - .rx_k_m1( rx0_k_m1 ), - .rx_k_m2( rx0_k_m2 ), - .rx_k_m3( rx0_k_m3), - .rx_k_m4( rx0_k_m4 ), - .rx_data_m1( rx0_data_m1 ), - .rx_data_m2( rx0_data_m2 ), - .rx_data_m3( rx0_data_m3), - .rx_data_m4( rx0_data_m4 ), - // Param RAM - .dpr_ad( ), - .dpr_we( ), - .dpr_ce( ), - .dpr_di( 9'h0), - .dpr_do( ), - // Metrics and Interrupts - .mac_int( mac_int[0] ), - .rx_sop( rx_sop[0] ), - .rx_eop( rx_eop[0] ), - .tx_sop( tx_sop[0] ), - .tx_eop( tx_eop[0] ), - .metrics_start ( ), - .metrics_d ( 9'h0 ), - .rx_active( mac_rx_active[0] ), - .tx_active( mac_tx_active[0] ) -); - - -ipv4_rx ipv4_rx_0( - .rstn( rstn ), - .clk( pcs_pclk ), - // control - .phy_resetn ( phy_resetn[0] ), - .phy_up( phy_up[0] ), - // packet data - .pkt_start( ipv4_pkt_start[0] ), - .rx_eop( rx_eop[0] ), - .rx_data_m1( rx0_data_m1 ), - .rx_data_m2( rx0_data_m2 ), - .rx_data_m3( rx0_data_m3), - .rx_data_m4( rx0_data_m4 ), - // flags - .pkt_complete(ipv4_pkt_complete[0]), - .trigger_src_addr( ), - .trigger_dst_addr( trigger[0] ), - .keep( ) - ); - - -pkt_filter pkt_filter_01( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_01 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx0_data_m1 ), - .rx_data_m2( rx0_data_m2 ), - .rx_data_m3( rx0_data_m3), - .rx_data_m4( rx0_data_m4 ), - // filter - .new_frame ( rx_sop[0] ), - .block( 1'b0 ), - .invert( 1'b1 ), - .trigger( trigger[0] ), - .keep( rx_pf_keep_01 ) -); - -drop_fifo drop_fifo_01( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b1 ), - // control - .keep ( rx_pf_keep_01 | rx_mac_keep[0] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[0] ), - .wr_done( rx_sc_wr_done[0] ), - .d_in( rx_sc_fifo_d0 ), - // output - .we_out( rx_df_fifo_we_01 ), - .d_out( rx_df_fifo_d_01 ), - // debug - .active( drop_rx0_active[1] ) -); - -sync_fifo sync_fifo_rx_01( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input - .we ( rx_df_fifo_we_01 & phy_up[1] ), - .d_in ( rx_df_fifo_d_01 ), - // output - .re ( rx_sw_fifo_re_01 ), - .d_out( rx_sf_fifo_d_01 ), - .empty( rx_sf_fifo_empty_01 ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx0_active[1] ) -); - -pkt_filter pkt_filter_02( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_02 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx0_data_m1 ), - .rx_data_m2( rx0_data_m2 ), - .rx_data_m3( rx0_data_m3), - .rx_data_m4( rx0_data_m4 ), - // filter - .new_frame ( rx_sop[0] ), - .block( rx_sf_almost_full_02 ), - .invert( 1'b1 ), - .trigger( trigger[0] ), - .keep( rx_pf_keep_02 ) -); - -drop2_fifo drop_fifo_02( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b1 ), - // control - .keep ( rx_pf_keep_02 | rx_mac_keep[0] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[0] ), - .wr_done( rx_sc_wr_done[0] ), - .d_in( rx_sc_fifo_d0 ), - // output - .we_out( rx_df_fifo_we_02 ), - .d_out( rx_df_fifo_d_02 ), - .active( drop_rx0_active[2] ) - ); - -sync_fifo sync_fifo_rx_02( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input - .we ( rx_df_fifo_we_02 & phy_up[2] ), - .d_in ( rx_df_fifo_d_02 ), - // output - .re ( rx_sw_fifo_re_02 ), - .d_out( rx_sf_fifo_d_02 ), - .empty( rx_sf_fifo_empty_02 ), - .almost_full( rx_sf_almost_full_02 ), - .reset_ptrs( 1'b0 ), - // debug - .active(sync_rx0_active[2] ) -); - - -pkt_filter pkt_filter_03( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_03 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx0_data_m1 ), - .rx_data_m2( rx0_data_m2 ), - .rx_data_m3( rx0_data_m3), - .rx_data_m4( rx0_data_m4 ), - // filter - .new_frame ( rx_sop[0] ), - .block( rx_sf_almost_full_03 ), - .invert( 1'b0 ), - .trigger( trigger[0] ), - .keep( rx_pf_keep_03 ) - ); - -drop_fifo drop_fifo_03( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b0 ), - // control - .keep ( rx_pf_keep_03 | rx_mac_keep[0] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[0] ), - .wr_done( rx_sc_wr_done[0] ), - .d_in( rx_sc_fifo_d0 ), - // output - .we_out( rx_df_fifo_we_03 ), - .d_out( rx_df_fifo_d_03 ), - .active( drop_rx0_active[3] ) - ); - -sync_fifo sync_fifo_rx_03( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input - .we ( rx_df_fifo_we_03 & phy_up[3] ), - .d_in ( rx_df_fifo_d_03 ), - // output - .re ( rx_sw_fifo_re_03 ), - .d_out( rx_sf_fifo_d_03 ), - .empty( rx_sf_fifo_empty_03 ), - .almost_full( rx_sf_almost_full_03 ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx0_active[3] ) - ); - -fcs fcs_0( - .rstn( rstn ), - .clk( pcs_pclk ), - .init( fcs_init[0] ), - .enable( fcs_enable[0] ), - .addr( fcs_addr0 ), - .din( fcs_din0 ), - .dout( fcs_dout0 ) -); - - -mac mac_1( - .rstn( ~mac_reset[1] ), - .phy_resetn ( phy_resetn[1] ), - .clk( pcs_pclk ), - .tap_port ( 1'b0 ), - // SGMII AN - .link_timer( 1'b0 ), - .fixed_speed(SGMII_SPEED_AN), - .an_disable( 1'b0 ), - .an_link_up( ), - .an_duplex( ), - .mode_100Mbit( mode_100Mbit[1] ), - .phy_up( phy_up[1] ), - // Switch I/F - .tx_mode( tx_sw_mode1 ), - .tx_f( tx_sc_done[1] ), - // PCS / SERDES health - .rx_lsm( sgmii_lsm_status[1] ), - .rx_cv_err ( sgmii_rx_cv_err[1] ), - .rx_disp_err( sgmii_rx_disp_err[1] ), - .rx_cdr_lol( sgmii_rx_cdr_lol[1] ), - .rx_los ( sgmii_rx_los_low[1] ), - // PCS data I/F - .rx_k( sgmii_rx_k[1] ), - .rx_data( rx_data1 ), - .tx_k( sgmii_tx_k[1] ), - .tx_data( tx_data1 ), - .tx_disp_correct( sgmii_tx_disp_correct[1] ), - // Flags and Interrupts - .keep( rx_mac_keep[1] ), - // FCS - .fcs_init( fcs_init[1] ), - .fcs_enable( fcs_enable[1] ), - .fcs_addr( fcs_addr1 ), - .fcs_dout( fcs_din1 ), - .fcs_din( fcs_dout1 ), - // SGMII RX / FIFO Write - .rx_fifo_we( rx_sc_fifo_we[1] ), - .rx_fifo_d( rx_sc_fifo_d1 ), - .rx_error( rx_sc_error[1] ), - .rx_wr_done( rx_sc_wr_done[1] ), - // SGMII TX / FIFO Read - .tx_fifo_re( tx_sc_fifo_re[1] ), - .tx_fifo_d( tx_sw_fifo_d1 ), - .tx_fifo_empty( tx_sw_fifo_empty[1] ), - // Packet Filter - .rx_sample( ), - .ipv4_pkt_start( ipv4_pkt_start[1] ), - .trigger( ), - .rx_enet_bcast( rx_enet_bcast[1] ), - .rx_ipv4_arp( rx_ipv4_arp[1] ), - .rx_k_m1( rx1_k_m1 ), - .rx_k_m2( rx1_k_m2 ), - .rx_k_m3( rx1_k_m3), - .rx_k_m4( rx1_k_m4 ), - .rx_data_m1( rx1_data_m1 ), - .rx_data_m2( rx1_data_m2 ), - .rx_data_m3( rx1_data_m3), - .rx_data_m4( rx1_data_m4 ), - // Param RAM - .dpr_ad( ), - .dpr_we( ), - .dpr_ce( ), - .dpr_di( 9'h0), - .dpr_do( ), - // Metrics and Interrupts - .mac_int( mac_int[1] ), - .rx_sop( rx_sop[1] ), - .rx_eop( rx_eop[1] ), - .tx_sop( tx_sop[1] ), - .tx_eop( tx_eop[1] ), - .metrics_start ( ), - .metrics_d ( 9'h0 ), - .rx_active( mac_rx_active[1] ), - .tx_active( mac_tx_active[1] ) -); - -ipv4_rx ipv4_rx_1( - .rstn( rstn ), - .clk( pcs_pclk ), - // control - .phy_resetn ( phy_resetn[1] ), - .phy_up( phy_up[1] ), - // packet data - .pkt_start( ipv4_pkt_start[1] ), - .rx_eop( rx_eop[1] ), - .rx_data_m1( rx1_data_m1 ), - .rx_data_m2( rx1_data_m2 ), - .rx_data_m3( rx1_data_m3), - .rx_data_m4( rx1_data_m4 ), - // flags - .pkt_complete(ipv4_pkt_complete[1]), - .trigger_src_addr( ), - .trigger_dst_addr( trigger[1] ), - .keep( ) - ); - -pkt_filter #(.DEPTH(8), .DEPTHW(3), .WIDTH(32)) pkt_filter_10( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_10 ), - .we( mem_we ), - .addr( mem_addr[4:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx1_data_m1 ), - .rx_data_m2( rx1_data_m2 ), - .rx_data_m3( rx1_data_m3), - .rx_data_m4( rx1_data_m4 ), - // filter - .new_frame ( rx_sop[1] ), - .block( 1'b0 ), - .invert( 1'b1 ), - .trigger( trigger[1] ), - .keep( rx_pf_keep_10 ) - ); - -drop_fifo drop_fifo_10( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b1 ), - // control - .keep ( rx_pf_keep_10 | rx_mac_keep[1] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[1] ), - .wr_done( rx_sc_wr_done[1] ), - .d_in( rx_sc_fifo_d1 ), - // output - .we_out( rx_df_fifo_we_10 ), - .d_out( rx_df_fifo_d_10 ), - // debug - .active( drop_rx1_active[0] ) - ); - -sync_fifo sync_fifo_rx_10( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input / RX - .we ( rx_df_fifo_we_10 & phy_up[0] ), - .d_in ( rx_df_fifo_d_10 ), - // output / TX - .re ( rx_sw_fifo_re_10 ), - .d_out( rx_sf_fifo_d_10 ), - .empty( rx_sf_fifo_empty_10 ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx1_active[0] ) -); - -pkt_filter pkt_filter_12( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_12 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx1_data_m1 ), - .rx_data_m2( rx1_data_m2 ), - .rx_data_m3( rx1_data_m3), - .rx_data_m4( rx1_data_m4 ), - // filter - .new_frame ( rx_sop[1] ), - .block( rx_sf_almost_full_12 ), - .invert( 1'b0 ), - .trigger( trigger[1] ), - .keep( rx_pf_keep_12 ) - ); - -drop_fifo drop_fifo_12( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b0 ), - // control - .keep ( rx_pf_keep_12 | rx_mac_keep[1] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[1] ), - .wr_done( rx_sc_wr_done[1] ), - .d_in( rx_sc_fifo_d1 ), - // output - .we_out( rx_df_fifo_we_12 ), - .d_out( rx_df_fifo_d_12 ), - // debug - .active( drop_rx1_active[2] ) - ); - -sync_fifo sync_fifo_rx_12( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input / RX - .we ( rx_df_fifo_we_12 & phy_up[2] ), - .d_in ( rx_df_fifo_d_12 ), - // output / TX - .re ( rx_sw_fifo_re_12 ), - .d_out( rx_sf_fifo_d_12 ), - .empty( rx_sf_fifo_empty_12 ), - .almost_full( rx_sf_almost_full_12 ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx1_active[2] ) -); - -pkt_filter pkt_filter_13( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_13 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx1_data_m1 ), - .rx_data_m2( rx1_data_m2 ), - .rx_data_m3( rx1_data_m3), - .rx_data_m4( rx1_data_m4 ), - // filter - .new_frame ( rx_sop[1] ), - .block( 1'b0 ), - .invert( 1'b1 ), - .trigger( trigger[1] ), - .keep( rx_pf_keep_13 ) - ); - -drop_fifo drop_fifo_13( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b1 ), - // control - .keep ( rx_pf_keep_13 | rx_mac_keep[1] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[1] ), - .wr_done( rx_sc_wr_done[1] ), - .d_in( rx_sc_fifo_d1 ), - // output - .we_out( rx_df_fifo_we_13 ), - .d_out( rx_df_fifo_d_13 ), - // debug - .active( drop_rx1_active[3] ) - ); - -sync_fifo sync_fifo_rx_13( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input / RX - .we ( rx_df_fifo_we_13 & phy_up[3] ), - .d_in ( rx_df_fifo_d_13 ), - // output / TX - .re ( rx_sw_fifo_re_13 ), - .d_out( rx_sf_fifo_d_13 ), - .empty( rx_sf_fifo_empty_13 ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx1_active[3] ) - ); - -fcs fcs_1( - .rstn( rstn ), - .clk( pcs_pclk ), - .init( fcs_init[1] ), - .enable( fcs_enable[1] ), - .addr( fcs_addr1 ), - .din( fcs_din1 ), - .dout( fcs_dout1 ) -); - -metrics metrics_2( - .rstn( rstn ), - .clk( pcs_pclk ), - .mode_100Mbit( mode_100Mbit[2] ), - // input data for gathering metrics - .rx_mac_keep( rx_mac_keep ), - .rx_pf_keep_01( rx_pf_keep_01 ), - .rx_pf_keep_02( rx_pf_keep_02 ), - .rx_pf_keep_10( rx_pf_keep_10 ), - .rx_pf_keep_12( rx_pf_keep_12 ), - .rx_pf_keep_20( rx_pf_keep_20 ), - .rx_pf_keep_21( rx_pf_keep_21 ), - .rx_pf_keep_23( rx_pf_keep_23 ), - - .rx_sop( rx_sop ), - .rx_eop( rx_eop ), - .tx_sop( tx_sop ), - .tx_eop( tx_eop ), - // metric outputs - .metrics_start ( metrics_start ), - .metrics_d( metrics_d ) -); - - -mac mac_2( - .rstn( ~mac_reset[2] & ~sgmii_rx_los_low[2] ), - .phy_resetn ( phy_resetn[2] ), - .clk( pcs_pclk ), - .tap_port ( 1'b0 ), - // SGMII AN - .link_timer( 1'b0 ), - .fixed_speed(SGMII_SPEED_1GBIT), - .an_disable( 1'b1 ), - .an_link_up( ), - .an_duplex( ), - .mode_100Mbit( mode_100Mbit[2] ), - .phy_up( phy_up[2] ), - // Switch I/F - .tx_mode( tx_sw_mode2 ), - .tx_f( tx_sc_done[2] ), - // PCS / SERDES health - .rx_lsm( sgmii_lsm_status[2] ), - .rx_cv_err ( sgmii_rx_cv_err[2] ), - .rx_disp_err( sgmii_rx_disp_err[2] ), - .rx_cdr_lol( sgmii_rx_cdr_lol[2] ), - .rx_los ( sgmii_rx_los_low[2] ), - // PCS data I/F - .rx_k( sgmii_rx_k[2] ), - .rx_data( rx_data2 ), - .tx_k( sgmii_tx_k[2] ), - .tx_data( tx_data2 ), - .tx_disp_correct( sgmii_tx_disp_correct[2] ), - // Flags and Interrupts - .keep( rx_mac_keep[2] ), - // FCS - .fcs_init( fcs_init[2] ), - .fcs_enable( fcs_enable[2] ), - .fcs_addr( fcs_addr2 ), - .fcs_dout( fcs_din2 ), - .fcs_din( fcs_dout2 ), - // SGMII RX / FIFO Write - .rx_fifo_we( rx_sc_fifo_we[2] ), - .rx_fifo_d( rx_sc_fifo_d2 ), - .rx_error( rx_sc_error[2] ), - .rx_wr_done( rx_sc_wr_done[2] ), - // SGMII TX / FIFO Read - .tx_fifo_re( tx_sc_fifo_re[2] ), - .tx_fifo_d( tx_sw_fifo_d2 ), - .tx_fifo_empty( tx_sw_fifo_empty[2]), - // Packet Filter - .rx_sample( ), - .ipv4_pkt_start( ipv4_pkt_start[2] ), - .trigger( ), - .rx_enet_bcast( rx_enet_bcast[2] ), - .rx_ipv4_arp( rx_ipv4_arp[2] ), - .rx_k_m1( rx2_k_m1 ), - .rx_k_m2( rx2_k_m2 ), - .rx_k_m3( rx2_k_m3), - .rx_k_m4( rx2_k_m4 ), - .rx_data_m1( rx2_data_m1 ), - .rx_data_m2( rx2_data_m2 ), - .rx_data_m3( rx2_data_m3), - .rx_data_m4( rx2_data_m4 ), - // Param RAM - .dpr_ad( param_phy2_addr ), - .dpr_we( param_phy2_we ), - .dpr_ce( param_phy2_ce ), - .dpr_di( param_phy2_din ), - .dpr_do( param_phy2_dout ), - // Metrics and Interrupts - .mac_int( mac_int[2] ), - .rx_sop( rx_sop[2] ), - .rx_eop( rx_eop[2] ), - .tx_sop( tx_sop[2] ), - .tx_eop( tx_eop[2] ), - .metrics_start ( metrics_start ), - .metrics_d( metrics_d ), - // Debug - .rx_active( mac_rx_active[2] ), - .tx_active( mac_tx_active[2] ) -); - -ipv4_rx ipv4_rx_2( - .rstn( rstn ), - .clk( pcs_pclk ), - // control - .phy_resetn ( phy_resetn[2] ), - .phy_up( phy_up[2] ), - // packet data - .pkt_start( ipv4_pkt_start[2] ), - .rx_eop( rx_eop[2] ), - .rx_data_m1( rx2_data_m1 ), - .rx_data_m2( rx2_data_m2 ), - .rx_data_m3( rx2_data_m3), - .rx_data_m4( rx2_data_m4 ), - // flags - .pkt_complete(ipv4_pkt_complete[2]), - .trigger_src_addr( ), - .trigger_dst_addr( trigger[2] ), - .keep( ) - ); - - -pkt_filter pkt_filter_20( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_20 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx2_data_m1 ), - .rx_data_m2( rx2_data_m2 ), - .rx_data_m3( rx2_data_m3), - .rx_data_m4( rx2_data_m4 ), - // filter - .new_frame ( rx_sop[2] ), - .block( rx_sf_almost_full_20 ), - .invert( 1'b1 ), - .trigger( trigger[2] ), - .keep( rx_pf_keep_20 ) -); - -drop_fifo drop_fifo_20( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b1 ), - // control - .keep ( rx_pf_keep_20 | rx_mac_keep[2] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[2] ), - .wr_done( rx_sc_wr_done[2] ), - .d_in( rx_sc_fifo_d2 ), - // output - .we_out( rx_df_fifo_we_20 ), - .d_out( rx_df_fifo_d_20 ), - // debug - .active( drop_rx2_active[0] ) - ); - - -sync4_fifo sync_fifo_rx_20( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input / RX - .we ( rx_df_fifo_we_20 & phy_up[0]), - .d_in ( rx_df_fifo_d_20 ), - // output / TX - .re ( rx_sw_fifo_re_20 ), - .d_out( rx_sf_fifo_d_20 ), - .empty( rx_sf_fifo_empty_20 ), - .almost_full( rx_sf_almost_full_20 ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx2_active[0] ) -); - -pkt_filter pkt_filter_21( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_21 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx2_data_m1 ), - .rx_data_m2( rx2_data_m2 ), - .rx_data_m3( rx2_data_m3), - .rx_data_m4( rx2_data_m4 ), - // filter - .new_frame ( rx_sop[2] ), - .block( 1'b0 ), - .invert( 1'b0 ), - .trigger( trigger[2] ), - .keep( rx_pf_keep_21 ) -); - -drop_fifo drop_fifo_21( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b0 ), - // control - .keep ( rx_pf_keep_21 | rx_mac_keep[2] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[2] ), - .wr_done( rx_sc_wr_done[2] ), - .d_in( rx_sc_fifo_d2 ), - // output - .we_out( rx_df_fifo_we_21 ), - .d_out( rx_df_fifo_d_21 ), - // debug - .active( drop_rx2_active[1] ) - ); - -sync_fifo sync_fifo_rx_21( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input / RX - .we ( rx_df_fifo_we_21 & phy_up[1] ), - .d_in ( rx_df_fifo_d_21 ), - // output - .re ( rx_sw_fifo_re_21 ), - .d_out( rx_sf_fifo_d_21 ), - .empty( rx_sf_fifo_empty_21 ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx2_active[1] ) -); - -pkt_filter pkt_filter_2u( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_2u ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx2_data_m1 ), - .rx_data_m2( rx2_data_m2 ), - .rx_data_m3( rx2_data_m3), - .rx_data_m4( rx2_data_m4 ), - // filter - .new_frame ( rx_sop[2] ), - .block( tx_uc_block ), - .invert( 1'b0 ), - .trigger( trigger[2] ), - .keep( rx_pf_keep_2u ) - ); - -drop_fifo drop_fifo_2u( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b0 ), - // control - .passthrough( 1'b0 ), - .keep ( rx_pf_keep_2u | rx_mac_keep[2] ), - // input - .we_in( rx_sc_fifo_we[2] ), - .wr_done( rx_sc_wr_done[2] ), - .d_in( rx_sc_fifo_d2 ), - // output - .we_out( rx_df_fifo_we_2u ), - .d_out( rx_df_fifo_d_2u ), - // debug - .active( ) - ); - -sync_fifo sync_fifo_rx_2u( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input / RX - .we ( rx_df_fifo_we_2u ), - .d_in ( rx_df_fifo_d_2u ), - // output - .re ( rx_sw_fifo_re_2u ), - .d_out( rx_sf_fifo_d_2u ), - .empty( rx_sf_fifo_empty_2u ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( ) -); - -fcs fcs_2( - .rstn( rstn ), - .clk( pcs_pclk ), - .init( fcs_init[2] ), - .enable( fcs_enable[2] ), - .addr( fcs_addr2 ), - .din( fcs_din2 ), - .dout( fcs_dout2 ) -); - -mac mac_3( - .rstn( ~mac_reset[3] & ~sgmii_rx_los_low[3] ), - .phy_resetn ( phy_resetn[3] ), - .clk( pcs_pclk ), - .tap_port ( 1'b0 ), - // SGMII AN - .link_timer( 1'b0 ), - .fixed_speed(SGMII_SPEED_1GBIT), - .an_disable( 1'b1 ), - .an_link_up( ), - .an_duplex( ), - .mode_100Mbit( mode_100Mbit[3] ), - .phy_up( phy_up[3] ), - // Switch I/F - .tx_mode( tx_sw_mode3 ), - .tx_f( tx_sc_done[3] ), - // PCS / SERDES health - .rx_lsm( sgmii_lsm_status[3] ), - .rx_cv_err ( sgmii_rx_cv_err[3] ), - .rx_disp_err( sgmii_rx_disp_err[3] ), - .rx_cdr_lol( sgmii_rx_cdr_lol[3] ), - .rx_los ( sgmii_rx_los_low[3] ), - // PCS data I/F - .rx_k( sgmii_rx_k[3] ), - .rx_data( rx_data3 ), - .tx_k( sgmii_tx_k[3] ), - .tx_data( tx_data3 ), - .tx_disp_correct( sgmii_tx_disp_correct[3] ), - // Flags and Interrupts - .keep( rx_mac_keep[3] ), - // TX FCS - .fcs_init( fcs_init[3] ), - .fcs_enable( fcs_enable[3] ), - .fcs_addr( fcs_addr3 ), - .fcs_dout( fcs_din3 ), - .fcs_din( fcs_dout3 ), - // SGMII RX / FIFO Write - .rx_fifo_we( rx_sc_fifo_we[3] ), - .rx_fifo_d( rx_sc_fifo_d3 ), - .rx_error( rx_sc_error[3] ), - .rx_wr_done( rx_sc_wr_done[3] ), - // SGMII TX / FIFO Read - .tx_fifo_re( tx_sc_fifo_re[3] ), - .tx_fifo_d( tx_sw_fifo_d3 ), - .tx_fifo_empty( tx_sw_fifo_empty[3] ), - // Packet Filter - .rx_sample( rx_sample[3] ), - .ipv4_pkt_start( ipv4_pkt_start[3] ), - .trigger( ), - .rx_enet_bcast( rx_enet_bcast[3] ), - .rx_ipv4_arp( rx_ipv4_arp[3] ), - .rx_k_m1( rx3_k_m1 ), - .rx_k_m2( rx3_k_m2 ), - .rx_k_m3( rx3_k_m3), - .rx_k_m4( rx3_k_m4 ), - .rx_data_m1( rx3_data_m1 ), - .rx_data_m2( rx3_data_m2 ), - .rx_data_m3( rx3_data_m3), - .rx_data_m4( rx3_data_m4 ), - // Param RAM - .dpr_ad( ), - .dpr_we( ), - .dpr_ce( ), - .dpr_di( 9'h0), - .dpr_do( ), - // Metrics and Interrupts - .mac_int( mac_int[3] ), - .rx_sop( rx_sop[3] ), - .rx_eop( rx_eop[3] ), - .tx_sop( tx_sop[3] ), - .tx_eop( tx_eop[3] ), - .metrics_start ( ), - .metrics_d ( 9'h0 ), - // Debug - .rx_active( mac_rx_active[3] ), - .tx_active( mac_tx_active[3] ) - - ); - - -ipv4_rx ipv4_rx_3( - .rstn( rstn ), - .clk( pcs_pclk ), - // control - .phy_resetn ( phy_resetn[3] ), - .phy_up( phy_up[3] ), - // packet data - .pkt_start( ipv4_pkt_start[3] ), - .rx_eop( rx_eop[3] ), - .rx_data_m1( rx3_data_m1 ), - .rx_data_m2( rx3_data_m2 ), - .rx_data_m3( rx3_data_m3), - .rx_data_m4( rx3_data_m4 ), - // flags - .pkt_complete(ipv4_pkt_complete[3]), - .trigger_src_addr( ), - .trigger_dst_addr( trigger[3] ), - .keep( ) - ); - - - -pkt_filter pkt_filter_30( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_30 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx3_data_m1 ), - .rx_data_m2( rx3_data_m2 ), - .rx_data_m3( rx3_data_m3), - .rx_data_m4( rx3_data_m4 ), - // filter - .new_frame ( rx_sop[3] ), - .block( 1'b0 ), - .invert( 1'b0 ), - .trigger( trigger[3] ), - .keep( rx_pf_keep_30 ) - ); - -drop_fifo drop_fifo_30( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b0 ), - // control - .keep ( rx_pf_keep_30 | rx_mac_keep[3] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[3] ), - .wr_done( rx_sc_wr_done[3] ), - .d_in( rx_sc_fifo_d3 ), - // output - .we_out( rx_df_fifo_we_30 ), - .d_out( rx_df_fifo_d_30 ), - // debug - .active( drop_rx3_active[0] ) - ); - -sync_fifo sync_fifo_rx_30( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input - .we ( rx_df_fifo_we_30 & phy_up[0] ), - .d_in ( rx_df_fifo_d_30 ), - // output - .re ( rx_sw_fifo_re_30 ), - .d_out( rx_sf_fifo_d_30 ), - .empty( rx_sf_fifo_empty_30 ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx3_active[0] ) - ); - -pkt_filter pkt_filter_31( - .rstn( rstn ), - .clk( pcs_pclk ), - // input for programming - .sel( pkt_filter_sel_31 ), - .we( mem_we ), - .addr( mem_addr[3:0] ), - .d_in( mem_d_i[7:0] ), - // registered data - .rx_data_m1( rx3_data_m1 ), - .rx_data_m2( rx3_data_m2 ), - .rx_data_m3( rx3_data_m3), - .rx_data_m4( rx3_data_m4 ), - // filter - .new_frame ( rx_sop[3] ), - .block( 1'b0 ), - .invert( 1'b1 ), - .trigger( trigger[3] ), - .keep( rx_pf_keep_31 ) - ); - -drop_fifo drop_fifo_31( - .rstn( rstn ), - .clk ( pcs_pclk ), - .enable( 1'b1 ), - // control - .keep ( rx_pf_keep_31 | rx_mac_keep[3] ), - .passthrough( 1'b0 ), - // input - .we_in( rx_sc_fifo_we[3] ), - .wr_done( rx_sc_wr_done[3] ), - .d_in( rx_sc_fifo_d3 ), - // output - .we_out( rx_df_fifo_we_31 ), - .d_out( rx_df_fifo_d_31 ), - // debug - .active( drop_rx3_active[1] ) - ); - -sync_fifo sync_fifo_rx_31( - .rstn( rstn ), - .clk ( pcs_pclk ), - // input - .we ( rx_df_fifo_we_31 & phy_up[1] ), - .d_in ( rx_df_fifo_d_31 ), - // output - .re ( rx_sw_fifo_re_31 ), - .d_out( rx_sf_fifo_d_31 ), - .empty( rx_sf_fifo_empty_31 ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( sync_rx3_active[1] ) - ); - -fcs fcs_3( - .rstn( rstn ), - .clk( pcs_pclk ), - .init( fcs_init[3] ), - .enable( fcs_enable[3] ), - .addr( fcs_addr3 ), - .din( fcs_din3 ), - .dout( fcs_dout3 ) -); - -/* - * uCont i/f FIFO - * FIFO side connects to network switch - * RX: processor writes (data into switch) - * TX: processor reads (data from switch) - */ -half_fifo #(.DPRAM_DEPTH(9)) micro_fifo_0 ( - .rstn( rstn ), - .uc_clk(clk_10), - .fifo_clk(pcs_pclk), - // UC interrupt support - .fifo_we_int ( micro_fifo_int ), - // TX mode - .tx_mode(tx_sw_modeu), - // DPRAM common - .dpram_addr( mem_addr[8:0] ), - .dpram_din( mem_d_i[8:0] ), - .dpram_dout( micro_fifo_do ), - .dpram_we( mem_we ), - .dpram_oe( mem_oe ), - // UC select signals - .dpram_ptrs_sel( dpram_ptrs_sel ), - .dpram_rx_sel( dpram_rx_sel ), - .dpram_tx_sel( dpram_tx_sel ), - // FIFO TX (input) - .fifo_we( tx_sw_fifo_we ), - .fifo_d_in( tx_sw_fifo_du ), - // FIFO RX (output) - .fifo_re( rx_sw_fifo_re_u2 ), - .fifo_d_out( rx_uc_fifo_d_u2 ), - // FIFO flags - .rx_empty( rx_uc_fifo_empty_u2 ), - .tx_full ( tx_uc_block ) - ); - -/* - * Param RAM - */ -dpram param_ram_2( - .rstn( rstn ), - .a_clk( fb_clk ), - .a_clk_e( param_sel[2] ), - .a_we( mem_we ), - .a_oe( 1'b0 ), - .a_addr( mem_addr ), - .a_din( mem_d_i[8:0] ), - .a_dout( ), - // port B - .b_clk( pcs_pclk ), - .b_clk_e( param_phy2_ce ), - .b_we( param_phy2_we ), - .b_oe( 1'b1 ), - .b_addr( param_phy2_addr ), - .b_din( param_phy2_dout ), - .b_dout( param_phy2_din ) -); - -/* - * PCS block that encapsulates two DCUs and the SCI block - */ -pcs pcs_0 ( - - .refclk0_refclkn(refclkp_d0), - .refclk0_refclkp(refclkn_d0), - .refclk0_refclko( refclko ), - - // cross DCU tie offs - .sgmii0_cyawstn( 1'b0 ), - - //DCU0 CH0 to PHY0 - .sgmii0_hdinn(sgmii0_hdinn), - .sgmii0_hdinp(sgmii0_hdinp), - .sgmii0_hdoutn(sgmii0_hdoutn), - .sgmii0_hdoutp(sgmii0_hdoutp), - - // DCU resets - .sgmii0_tx_serdes_rst_c( tx_serdes_rst[0] ), // rset LOL signal in PLL - .sgmii0_rst_dual_c( pcs_rst_dual[0] ), // resets all serdes channels including aux and PCS - .sgmii0_serdes_rst_dual_c( serdes_rst_dual[0] ), // resets serdes dual gated by fpga_reset_enable - - // channel resets - .sgmii0_rx_pcs_rst_c( rx_pcs_rst[0] ), // reset channel PCS logic - .sgmii0_rx_serdes_rst_c( rx_serdes_rst[0] ), // reset digital logic in serdes rx - .sgmii0_tx_pcs_rst_c( tx_pcs_rst[0] ), // reset channel PCS logic - - .sgmii0_rx_pwrup_c(1'b1), // channel power up - .sgmii0_tx_pwrup_c(1'b1), // channel power up - - /* tx_pclk: Transmit Primary Clock. Direct connection to Primary - * clock network. When gearing is not enabled, this output - * equals the transmit full rate clock. When 2:1 gearing - * is enabled, it is a divide-by-2 half-rate clock. - */ - .sgmii0_tx_pclk( pcs_pclk ), // direct connection from primary clock network - .sgmii0_txi_clk( pcs_pclk ), // clocks the TX UI FIFOS (see Figure 27) - - .sgmii0_tx_disp_correct(sgmii_tx_disp_correct[0]), - .sgmii0_tx_k(sgmii_tx_k[0]), - .sgmii0_txdata( tx_data0 ), - .sgmii0_xmit(1'b0), - .sgmii0_signal_detect_c(1'b1), - .sgmii0_rx_cv_err( sgmii_rx_cv_err[0] ), // code violation with associated data, PCS will drive 0xEE and K=1 (Table 9-4) - .sgmii0_rx_disp_err( sgmii_rx_disp_err[0] ), - .sgmii0_rx_k( sgmii_rx_k[0] ), - .sgmii0_rxdata( rx_data0 ), - .sgmii0_lsm_status_s( sgmii_lsm_status[0] ), // lane is synced with commas ( 0 means no commas detected ) - .sgmii0_rx_cdr_lol_s( sgmii_rx_cdr_lol[0] ), // CDR Loss of lock - .sgmii0_rx_los_low_s( sgmii_rx_los_low[0] ), // Loss of signal (LO THRESHOLD RANGE) detection - - .sgmii0_ctc_ins_s(), // skip char added by CTC - .sgmii0_ctc_orun_s(), // CTC FIFO over run error - .sgmii0_ctc_urun_s(), // CTC FIFO under run error - .sgmii0_ctc_del_s(), // skip char deleted by CTC - .sgmii0_pll_lol( pll_lol[0] ), - - //DCU0 CH1 to PHY1 - .sgmii1_hdinn( sgmii1_hdinn ), - .sgmii1_hdinp( sgmii1_hdinp ), - .sgmii1_hdoutn( sgmii1_hdoutn ), - .sgmii1_hdoutp( sgmii1_hdoutp ), - - // DCU resets - .sgmii1_rst_dual_c( pcs_rst_dual[0] ), - .sgmii1_serdes_rst_dual_c( serdes_rst_dual[0] ), - .sgmii1_tx_serdes_rst_c( tx_serdes_rst[0] ), - - // Channel resets - .sgmii1_rx_pcs_rst_c( rx_pcs_rst[1] ), - .sgmii1_rx_serdes_rst_c( rx_serdes_rst[1] ), - .sgmii1_tx_pcs_rst_c( tx_pcs_rst[1] ), - - .sgmii1_rx_pwrup_c( 1'b1 ), - .sgmii1_tx_pwrup_c( 1'b1 ), - .sgmii1_serdes_pdb( 1'b1 ), - - .sgmii1_tx_pclk( ), - .sgmii1_txi_clk( pcs_pclk ), - - .sgmii1_rx_cv_err( sgmii_rx_cv_err[1] ), - .sgmii1_rx_disp_err( sgmii_rx_disp_err[1] ), - .sgmii1_rx_k( sgmii_rx_k[1] ), - .sgmii1_rxdata( rx_data1 ), - .sgmii1_tx_disp_correct( sgmii_tx_disp_correct[1] ), - .sgmii1_tx_k( sgmii_tx_k[1] ), - .sgmii1_txdata( tx_data1 ), - .sgmii1_xmit( 1'b0 ), - - .sgmii1_signal_detect_c( 1'b1 ), - - .sgmii1_ctc_del_s(), - .sgmii1_ctc_ins_s(), - .sgmii1_ctc_orun_s(), - .sgmii1_ctc_urun_s(), - - .sgmii1_lsm_status_s( sgmii_lsm_status[1] ), - .sgmii1_rx_cdr_lol_s( sgmii_rx_cdr_lol[1] ), - .sgmii1_rx_los_low_s( sgmii_rx_los_low[1] ), - - // DCU1 CH0 to Expansion - .sgmii2_hdinn( sgmii2_hdinn ), - .sgmii2_hdinp( sgmii2_hdinp ), - .sgmii2_hdoutn( sgmii2_hdoutn ), - .sgmii2_hdoutp( sgmii2_hdoutp ), - - // DCU Tie Offs - .sgmii2_cyawstn( 1'b0 ), - - // DCU resets - .sgmii2_rst_dual_c( pcs_rst_dual[1] ), - .sgmii2_serdes_rst_dual_c( serdes_rst_dual[1] ), - .sgmii2_tx_serdes_rst_c( tx_serdes_rst[1] ), - - // Channel resets - .sgmii2_rx_pcs_rst_c( rx_pcs_rst[2] ), - .sgmii2_rx_serdes_rst_c( rx_serdes_rst[2] ), - .sgmii2_tx_pcs_rst_c( tx_pcs_rst[2] ), - - .sgmii2_rx_pwrup_c( 1'b1 ), - .sgmii2_tx_pwrup_c( 1'b1 ), - .sgmii2_serdes_pdb( 1'b1 ), - - .sgmii2_tx_pclk( ), - .sgmii2_txi_clk( pcs_pclk ), - - .sgmii2_rx_cv_err( sgmii_rx_cv_err[2] ), - .sgmii2_rx_disp_err( sgmii_rx_disp_err[2] ), - .sgmii2_rx_k( sgmii_rx_k[2] ), - .sgmii2_rxdata( rx_data2 ), - .sgmii2_tx_disp_correct( sgmii_tx_disp_correct[2] ), - .sgmii2_tx_k( sgmii_tx_k[2] ), - .sgmii2_txdata( tx_data2 ), - .sgmii2_xmit( 1'b0 ), - - .sgmii2_signal_detect_c( 1'b1 ), - - .sgmii2_ctc_del_s(), - .sgmii2_ctc_ins_s(), - .sgmii2_ctc_orun_s(), - .sgmii2_ctc_urun_s(), - - .sgmii2_lsm_status_s( sgmii_lsm_status[2] ), - .sgmii2_rx_cdr_lol_s( sgmii_rx_cdr_lol[2] ), - .sgmii2_rx_los_low_s( sgmii_rx_los_low[2] ), - - .sgmii2_pll_lol( pll_lol[1] ), - - // DCU1 CH1 to Expansion - .sgmii3_hdinn( sgmii3_hdinn ), - .sgmii3_hdinp( sgmii3_hdinp ), - .sgmii3_hdoutn( sgmii3_hdoutn ), - .sgmii3_hdoutp( sgmii3_hdoutp ), - - // DCU resets - .sgmii3_rst_dual_c( pcs_rst_dual[1] ), - .sgmii3_serdes_rst_dual_c( serdes_rst_dual[1] ), - .sgmii3_tx_serdes_rst_c( tx_serdes_rst[1] ), - - // Channel resets - .sgmii3_rx_pcs_rst_c( rx_pcs_rst[3] ), - .sgmii3_rx_serdes_rst_c( rx_serdes_rst[3] ), - .sgmii3_tx_pcs_rst_c( tx_pcs_rst[3] ), - - .sgmii3_rx_pwrup_c( 1'b1 ), - .sgmii3_tx_pwrup_c( 1'b1 ), - - .sgmii3_tx_pclk( ), - .sgmii3_txi_clk( pcs_pclk ), - - .sgmii3_rx_cv_err( sgmii_rx_cv_err[3] ), - .sgmii3_rx_disp_err( sgmii_rx_disp_err[3] ), - .sgmii3_rx_k( sgmii_rx_k[3] ), - .sgmii3_rxdata( rx_data3 ), - .sgmii3_tx_disp_correct( sgmii_tx_disp_correct[3] ), - .sgmii3_tx_k( sgmii_tx_k[3] ), - .sgmii3_txdata( tx_data3 ), - .sgmii3_xmit( 1'b0 ), - - .sgmii3_signal_detect_c( 1'b1 ), - - .sgmii3_ctc_del_s(), - .sgmii3_ctc_ins_s(), - .sgmii3_ctc_orun_s(), - .sgmii3_ctc_urun_s(), - - .sgmii3_lsm_status_s( sgmii_lsm_status[3] ), - .sgmii3_rx_cdr_lol_s( sgmii_rx_cdr_lol[3] ), - .sgmii3_rx_los_low_s( sgmii_rx_los_low[3] ), - - - // DCU0 SCI - .sgmii0_sci_sel_dual( sci_sel_dual[0] ), - .sgmii0_sci_en_dual( 1'b1 ), - .sgmii0_sci_addr( mem_addr[5:0] ), // SCI Register Address Bits - .sgmii0_sci_rddata( sci_rddata0 ), - .sgmii0_sci_wrdata( mem_d_i[7:0] ), - .sgmii0_sci_rd( ~fb_oen ), - .sgmii0_sci_wrn( fb_rwn ), - - - .sgmii0_sci_sel( sci_sel_ch[0] ), - .sgmii0_sci_en( 1'b1 ), - - .sgmii1_sci_sel( sci_sel_ch[1] ), - .sgmii1_sci_en( 1'b1 ), - - .sgmii0_sci_int( sci_int[1] ), - - // DCU1 SCI - .sgmii2_sci_sel_dual( sci_sel_dual[1] ), - .sgmii2_sci_en_dual( 1'b1 ), - .sgmii2_sci_addr( mem_addr[5:0] ), // SCI Register Address Bits - .sgmii2_sci_rddata( sci_rddata1 ), - .sgmii2_sci_wrdata( mem_d_i[7:0] ), - .sgmii2_sci_rd( ~fb_oen ), - .sgmii2_sci_wrn( fb_rwn ), - - .sgmii2_sci_sel( sci_sel_ch[2] ), - .sgmii2_sci_en( 1'b1 ), - - .sgmii2_sci_int( sci_int[0] ), - - .sgmii3_sci_sel( sci_sel_ch[3] ) - -); - - - -mdio_controller #(.ADDR_SZ( MDIO_ROM_ADDR_SZ )) mdio_controller_0 -( - .rstn(rstn), - .clk(clk_10), - .work_start(mdio_cont_work_start), - .work_run(mdio_cont_work_run), - .work_done(mdio_cont_work_done), - .routine_addr( mdio_routine_addr ), - .buffer_full(1'b0), - .addr(rom_a), - .di(rom_d), - .reg_addr(mdio_reg_addr), - .dout(mdio_wd), - .ld(mdio_ld), - .rwn(mdio_rwn), - .done(mdio_done) -); - -mdio_data_ti #(.ADDR_SZ( MDIO_ROM_ADDR_SZ )) mdio_data_ti_0( - .ad( rom_a ), - .page( mdio_page_set ), - .reg_addr( mdio_reg_addr_set ), - .data_in_h( mdio_w_data_h_set ), - .data_in_l( mdio_w_data_l_set ), - .d( rom_d ), - .oe( 1'b1 ) -); - - -/* MDIO mux and output enables */ -always @(*) begin - case (mdio_mux_sel) - 2'b00: mdi = phy0_mdio; - 2'b01: mdi = phy1_mdio; - 2'b10: mdi = phy2_mdio; - 2'b11: mdi = 1'b1; - endcase -end - -assign phy0_mdio = (mdo_oe & ~mdio_mux_sel[1] & ~mdio_mux_sel[0]) ? mdo : 1'bz; -assign phy1_mdio = (mdo_oe & ~mdio_mux_sel[1] & mdio_mux_sel[0]) ? mdo : 1'bz; -assign phy2_mdio = (mdo_oe & mdio_mux_sel[1] & ~mdio_mux_sel[0]) ? mdo : 1'bz; - -mdio mdio_0( - .rstn(rstn), - .mdc(clk_10), - // MDIO - .mdi(mdi), - .mdo(mdo), - .mdo_oe(mdo_oe), - // mdio controller interface - .rwn(mdio_rwn), - .phy_addr(5'h00), - .reg_addr(mdio_reg_addr), - .di(mdio_wd), - .ld(mdio_ld), - .run( mdio_run ), - .done(mdio_done), // signal controller that mdio xfer is done - // output port to converter - .dout(mdio_rd), - .we( mdio_rd_we ) -); - - -spi spi_0 ( - .rstn(rstn), - .clk(clk_10), - // spi signals - .spi_cs( fpga_spics ), - .spi_clk( fpga_mclk ), - .spi_d_in( fpga_mosi), - .spi_d_o( spi_do ), - .spi_d_oe(spi_do_e ), - // internal FPGA memory - .mem_addr( mem_addr ), - .mux_sel ( mem_do_mux_sel ), - .d_i( mem_d_o ), - .d_o( mem_d_i ), - // individual memory selects - .we( mem_we ), - .oe( mem_oe ), - .dpram_tx_sel( dpram_tx_sel ), - .dpram_rx_sel( dpram_rx_sel ), - .dpram_ptrs_sel( dpram_ptrs_sel ), - .param_sel( param_sel ), - .pkt_filter_sel_01( pkt_filter_sel_01 ), - .pkt_filter_sel_02( pkt_filter_sel_02 ), - .pkt_filter_sel_03( pkt_filter_sel_03 ), - .pkt_filter_sel_10( pkt_filter_sel_10 ), - .pkt_filter_sel_12( pkt_filter_sel_12 ), - .pkt_filter_sel_13( pkt_filter_sel_13 ), - .pkt_filter_sel_20( pkt_filter_sel_20 ), - .pkt_filter_sel_21( pkt_filter_sel_21 ), - .pkt_filter_sel_23( pkt_filter_sel_23 ), - .pkt_filter_sel_2u( pkt_filter_sel_2u ), - .pkt_filter_sel_30( pkt_filter_sel_30 ), - .pkt_filter_sel_31( pkt_filter_sel_31 ), - .pkt_filter_sel_32( pkt_filter_sel_32 ), - .pkt_filter_sel_u2( pkt_filter_sel_u2 ), - .interrupts_sel( int_sel ), - .sci_sel_dual( sci_sel_dual ), - .sci_sel_ch( sci_sel_ch ) -); - -assign fpga_miso = spi_do_e ? spi_do : 1'bz; - -/* data mux out of internal memories */ -always@(*) -begin - case(mem_do_mux_sel) - 5'b00000: mem_d_o = { 2'b0, sci_rddata1 }; - 5'b00001: mem_d_o = { 2'b0, sci_rddata0 }; - 5'b00010: mem_d_o = { 1'b0, micro_fifo_do }; - 5'b00011: mem_d_o = { 1'b0, micro_fifo_do }; - 5'b00100: mem_d_o = { 1'b0, micro_fifo_do }; - 5'b10000: mem_d_o = { 2'b0, int_do }; - default: mem_d_o = 9'h0; - endcase -end - -interrupts interrupts_0( - .rstn( rstn ), - .clk( pcs_pclk ), - .uc_clk( clk_10 ), - // uC interface - .sel( int_sel ), - .we( mem_we ), - .addr( mem_addr[0] ), - .d_in( mem_d_i[6:0] ), - .d_out( int_do ), - // interrupt sources - .cont_int( micro_fifo_int ), - .phy_int ( { 2'b0, phy1_intn, phy0_intn }), - .mac_int ( { mac_int[3], mac_int[2], mac_int[1], mac_int[0] } ), - .int_o( fpga_int ) -); - - -assign i2c_sda = sda_oe ? sda_o : 1'bz; -assign i2c_scl = scl_oe ? scl_o : 1'bz; - -i2c i2c_0( - .rstn( rstn ), - .clk( clk_10 ), - // external I2C I/O - .scl_i( i2c_scl ), - .scl_o( scl_o ), - .scl_oe( scl_oe ), - .sda_i( i2c_sda ), - .sda_o( sda_o ), - .sda_oe( sda_oe ), - // shared memory and controller data output - .mem_do( i2c_d_o ), - // dedicated memory interface - .mem_ad( ), - .mem_we( ), - .mem_ce( ), - .mem_di( 8'haa ), - // dedicated controller write interface - .cont_we( i2c_cont_we ), - .cont_done( i2c_cont_done ), - // Controller->FIFO input interface - .fifo_re( i2c_fifo_re ), - .tx_fifo_empty( cont_fifo_empty ), - .fifo_di( fifo_r_d[6:0] ) -); - - -/* -* ext_sys_fifo delays and enables: -* we need the re delay since we need to generate a re pulse from the -* we need the mdio_we delay since the fifo is clocked twice: high and low data -* -*/ -always@ ( posedge clk_10 or negedge rstn ) - begin - if ( !rstn ) - begin - cont_fifo_re_m1 <= 1'b0; - cont_fifo_re_m2 <= 1'b0; - end - else - begin - cont_fifo_re_m1 <= i2c_fifo_re; - cont_fifo_re_m2 <= cont_fifo_re_m1; - end - end - -// create a single re pulse since i2c runs slow. -assign i_cont_fifo_re = cont_fifo_re_m1 & ~cont_fifo_re_m2; - -assign bin_to_ascii_we = mdio_rd_we | cont_rd_we; -assign bin_to_ascii_d_in = read_fifo_mux_sel ? mdio_rd : cont_rd; - -/* - * Input: MDIO writes - * Output: I2C read FIFO - */ -bin_to_ascii bin_to_ascii_0( - .rstn( rstn ), - .clk( clk_10 ), - .width ( 1'b1 ), - // mdio interface - .we_i ( bin_to_ascii_we ), - .d_in( bin_to_ascii_d_in ), - // mdio controller interface - .run ( bin_to_ascii_run ), - .done (), - .busy( 1'b0 ), - // fifo port - .we_o ( read_fifo_we ), - .d_out( read_fifo_d_i ) -); - -/* - * Input: bin_to_ascii - * Output: I2C read - */ -sync_fifo ext_sys_fifo_0( - .rstn( rstn ), - .clk ( clk_10 ), - // input - .we ( read_fifo_we ), - .d_in ( { 2'b0, read_fifo_d_i } ), - // output - .re ( i_cont_fifo_re ), - .d_out( fifo_r_d ), - .empty( cont_fifo_empty ), - .almost_full( ), - .reset_ptrs( 1'b0 ), - // debug - .active( ) -); - - -/* JTAG Enable for 2-bit external buffer */ -assign fpga_jtag_e =1'bz; - - -/* LED Assignment */ -assign led[0] = 1'b1; -assign led[1] = phy_up[0]; -assign led[2] = phy_up[1]; - - -/* Debug: rx_active and tx_active - * Intention is to use these as sample enables in Reveal or - * external triggering - */ -always @(posedge pcs_pclk or negedge rstn) - if ( !rstn ) - rx_active[2] <= 1'b0; - else if (mac_rx_active[2] || drop_rx2_active[0] || sync_rx2_active[0] ) - rx_active[2] <= 1'b1; - else - rx_active[2] <= 1'b0; - -always @(posedge pcs_pclk or negedge rstn) - if ( !rstn ) - tx_active[0] <= 1'b0; - else if (mac_tx_active[0]) - tx_active[0] <= 1'b1; - else - tx_active[0] <= 1'b0; - -assign sample_enable = rx_active[2] | tx_active[0]; - - -/* Debug and Arduino Expansion, see definitions.v */ -`ifdef DEBUG_SPI - assign ard_scl = fpga_mclk; - assign ard_sda = fpga_spics; - assign ard_rxd1 = spi_do_e ? spi_do : 1'bz; - assign ard_txd1 = fpga_mosi; -`elsif DEBUG_MDIO - assign ard_scl = phy_mdc; - assign ard_sda = phy0_mdio; - assign ard_rxd1 = 1'bz; - assign ard_txd1 = refclko; -`elsif DEBUG_I2C - assign ard_scl = i2c_scl; - assign ard_sda = sda_oe ? sda_o : i2c_sda; - assign ard_rxd1 = 1'bz; - assign ard_txd1 = sda_oe; -`else - assign ard_scl = fpga_int; - assign ard_sda = 1'bz; - assign ard_rxd1 = 1'bz; - assign ard_txd1 = 1'bz; -`endif - -`ifdef ARD_EXP_UART - assign ard_txd2 = uart_txd; - assign uart_rxd = ard_rxd2; -`else - assign ftdi_tdi_rxd = uart_txd; - assign uart_rxd = ftdi_tck_txd; -`endif - - assign pe0 = 1'bz; - assign pe1 = 1'bz; - assign pe3 = 1'bz; - assign pe4 = 1'bz; - assign pe5 = 1'bz; - assign pg5 = 1'bz; - assign ph3 = 1'bz; - assign ph4 = 1'bz; - -endmodule |