summaryrefslogtreecommitdiffhomepage
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/an.v122
-rw-r--r--source/controller.v20
-rw-r--r--source/directives.v (renamed from source/definitions.v)20
-rw-r--r--source/drop2_fifo.v255
-rw-r--r--source/drop_fifo.v188
-rw-r--r--source/ethernet_params.v13
-rw-r--r--source/link_timer.v67
-rw-r--r--source/mac.v380
-rw-r--r--source/pcs.v228
-rw-r--r--source/pkt_filter.v6
-rw-r--r--source/sgmii_params.v9
-rw-r--r--source/spi.v63
-rw-r--r--source/switch.v165
-rw-r--r--source/sync2_fifo.v141
-rw-r--r--source/sync4_fifo.v206
-rw-r--r--source/top.v2177
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

Highly Recommended Verilog Books