summaryrefslogtreecommitdiffhomepage
path: root/manufacturer/altera/cyclone10_lp/src/betsy.v
diff options
context:
space:
mode:
Diffstat (limited to 'manufacturer/altera/cyclone10_lp/src/betsy.v')
-rw-r--r--manufacturer/altera/cyclone10_lp/src/betsy.v1916
1 files changed, 1916 insertions, 0 deletions
diff --git a/manufacturer/altera/cyclone10_lp/src/betsy.v b/manufacturer/altera/cyclone10_lp/src/betsy.v
new file mode 100644
index 0000000..2116b34
--- /dev/null
+++ b/manufacturer/altera/cyclone10_lp/src/betsy.v
@@ -0,0 +1,1916 @@
+/*
+ * betsy.v
+ *
+ * Copyright (C) 2025 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.
+ * 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: top module for three instantiated Ethernet PHYs + controllers
+ *
+ *
+ */
+
+// `define PASSTHROUGH
+`define PHY2_PRESENT
+
+module betsy (
+ input rstn,
+ input clk_i, // 25Mhz
+
+ input phy0_clk,
+ output phy1_clk,
+
+`ifdef SIMULATION
+ output pll_locked_o,
+ output pclk_o,
+ output [2:0] phy_up_o,
+`endif
+
+ // PHY0 RGMII
+ output phy0_rstn,
+
+ input phy0_rx_clk,
+ input phy0_rx_ctl,
+ input [3:0] phy0_rx_d,
+
+ output phy0_tx_clk,
+ output phy0_tx_ctl,
+ output [3:0] phy0_tx_d,
+
+ output phy0_mdc,
+ inout phy0_mdio,
+
+ input phy0_intn, // TODO: resolve PWRDN input option
+ inout [1:0] phy0_gpio,
+
+ // PHY1 RGMII
+ output phy1_rstn,
+
+ input phy1_rx_clk,
+ input phy1_rx_ctl,
+ input [3:0] phy1_rx_d,
+
+ output phy1_tx_clk,
+ output phy1_tx_ctl,
+ output [3:0] phy1_tx_d,
+
+ output phy1_mdc,
+ inout phy1_mdio,
+
+ input phy1_intn,
+ inout [1:0] phy1_gpio,
+
+ // PHY2 RGMII
+ output phy2_rstn,
+
+ input phy2_rx_clk,
+ input phy2_rx_ctl,
+ input [3:0] phy2_rx_d,
+
+ output phy2_tx_clk,
+ output phy2_tx_ctl,
+ output[3:0] phy2_tx_d,
+
+ output phy2_mdc,
+ inout phy2_mdio,
+
+ input phy2_intn,
+ inout [1:0] phy2_gpio,
+
+ // FLASH
+ output flash_clk,
+ input flash_dqs,
+ output flash_seln,
+ inout [7:0] flash_d,
+
+ // Debug
+ output [2:0] fpga_led
+);
+
+`define INCLUDED
+`include "../../../../src/ethernet_params.v"
+`undef INCLUDED
+
+ /* PARAMS */
+ parameter NUM_PHYS = 3;
+ parameter NUM_PLLS = 1;
+ parameter MDIO_ROM_ADDR_SZ = 7;
+ parameter NUM_ML_IF = 3;
+
+ wire reset, pll_locked;
+ reg sys_rstn;
+ wire cont_clk, clk_25, clk_125;
+ wire pclk; // main fabric clock for Ethernet pipeline
+ reg [3:0] cnt_init;
+ reg [25:0] heart_beat_cnt;
+ wire [NUM_PHYS-1:0] phy_up;
+
+ `ifdef SIMULATION
+ assign pll_locked_o = pll_locked;
+ assign pclk_o = pclk;
+ assign phy_up_o = phy_up;
+ `endif
+
+ // misc resets
+ wire [NUM_PHYS-1:0] phy_resetn;
+ wire [NUM_PHYS-1:0] mac_reset;
+ wire [NUM_PHYS-1:0] phy_int;
+
+ wire [NUM_PHYS-1:0] rx_sample;
+
+ // receive data + ctl input
+ wire [1:0] rx0_ctl_i, rx1_ctl_i, rx2_ctl_i;
+ wire [7:0] rx0_d_i, rx1_d_i, rx2_d_i;
+
+ // transmit data + ctl output
+ wire [1:0] tx0_ctl, tx1_ctl, tx2_ctl;
+ wire [7:0] tx0_d, tx1_d, tx2_d;
+
+
+ // Delayed RX input data
+ reg [1:0] rx0_ctl_i_m1, rx0_ctl_i_m2, rx0_ctl_i_m3, rx0_ctl_i_m4;
+ reg [7:0] rx0_d_i_m1, rx0_d_i_m2, rx0_d_i_m3, rx0_d_i_m4;
+
+ reg [1:0] rx1_ctl_i_m1, rx1_ctl_i_m2, rx1_ctl_i_m3, rx1_ctl_i_m4;
+ reg [7:0] rx1_d_i_m1, rx1_d_i_m2, rx1_d_i_m3, rx1_d_i_m4;
+
+ reg [1:0] rx2_ctl_i_m1, rx2_ctl_i_m2, rx2_ctl_i_m3, rx2_ctl_i_m4;
+ reg [7:0] rx2_d_i_m1, rx2_d_i_m2, rx2_d_i_m3, rx2_d_i_m4;
+
+ // Delayed data shared between modules
+ wire [1:0] rx0_ctl_m1, rx0_ctl_m2, rx0_ctl_m3, rx0_ctl_m4;
+ wire [7:0] rx0_d_m1, rx0_d_m2, rx0_d_m3, rx0_d_m4;
+
+ wire [1:0] rx1_ctl_m1, rx1_ctl_m2, rx1_ctl_m3, rx1_ctl_m4;
+ wire [7:0] rx1_d_m1, rx1_d_m2, rx1_d_m3, rx1_d_m4;
+
+ wire [1:0] rx2_ctl_m1, rx2_ctl_m2, rx2_ctl_m3, rx2_ctl_m4;
+ wire [7:0] rx2_d_m1, rx2_d_m2, rx2_d_m3, rx2_d_m4;
+
+
+ // MAC asserts when it determines RX data should be kept
+ wire [NUM_PHYS-1:0] rx_mac_keep;
+ wire [NUM_PHYS-1:0] rx_mac_wr_done;
+
+ // drop filter outputs
+ wire rx_df_fifo_we_01, rx_df_fifo_we_02, rx_df_fifo_we_0u;
+ wire rx_df_fifo_we_10, rx_df_fifo_we_12;
+ wire rx_df_fifo_we_20, rx_df_fifo_we_21;
+
+ wire [8:0] rx_df_fifo_d_01, rx_df_fifo_d_02, rx_df_fifo_d_0u;
+ wire [8:0] rx_df_fifo_d_10, rx_df_fifo_d_12;
+ wire [8:0] rx_df_fifo_d_20, rx_df_fifo_d_21;
+ wire [8:0] rx_df_fifo_d_u0;
+
+ // pkt filter
+ wire [NUM_PHYS-1:0] trigger;
+ wire [NUM_PHYS-1:0] rx_enet_bcast;
+ wire [NUM_PHYS-1:0] rx_ipv4_arp;
+ wire rx_pf_keep_01, rx_pf_keep_02;
+ wire rx_pf_keep_10, rx_pf_keep_12;
+ wire rx_pf_keep_20, rx_pf_keep_21;
+ wire rx_pf_keep_0u;
+ wire rx_pf_keep_u0;
+
+ // rx_fifos
+ wire [NUM_PHYS-1:0] rx_mac_fifo_we;
+
+ // Read Enable from Switch to FIFO for transmit data
+ wire rx_sw_fifo_re_01, rx_sw_fifo_re_02, rx_sw_fifo_re_0u;
+ wire rx_sw_fifo_re_10, rx_sw_fifo_re_12;
+ wire rx_sw_fifo_re_20, rx_sw_fifo_re_21;
+ wire rx_sw_fifo_re_u0;
+
+ // FIFO empty flags from FIFO to switch
+ wire rx_sf_fifo_empty_01, rx_sf_fifo_empty_02, rx_sf_fifo_empty_0u;
+ wire rx_sf_fifo_empty_10, rx_sf_fifo_empty_12;
+ wire rx_sf_fifo_empty_20, rx_sf_fifo_empty_21;
+ wire rx_uc_fifo_empty_u0;
+
+ wire rx_sf_almost_full_01;
+ wire rx_sf_almost_full_10;
+ wire rx_sf_almost_full_20;
+ wire rx_sf_almost_full_0u;
+
+ // data from FIFO to switch
+ wire [8:0] rx_sf_fifo_d_01, rx_sf_fifo_d_02, rx_sf_fifo_d_0u;
+ wire [8:0] rx_sf_fifo_d_10, rx_sf_fifo_d_12;
+ wire [8:0] rx_sf_fifo_d_20, rx_sf_fifo_d_21;
+ wire [8:0] rx_uc_fifo_d_u0;
+
+ // data from MAC
+ wire [8:0] rx_mac_fifo_d0, rx_mac_fifo_d1, rx_mac_fifo_d2;
+
+ // RX byte cnt and mode from MAC
+ wire [1:0] rx0_mode, rx1_mode, rx2_mode;
+ wire [NUM_PHYS-1:0] rx_byte_cnt;
+ wire [10:0] rx0_mac_byte_cnt;
+ wire [10:0] rx1_mac_byte_cnt;
+ wire [10:0] rx2_mac_byte_cnt;
+ wire [10:0] rxu_byte_cnt, rx_mle_byte_cnt;
+
+ // ml_engine
+ wire mle_evt_start, mle_evt_active;
+ wire [NUM_ML_IF-1:0] mle_enable, mle_empty, mle_we;
+ wire mle_oe;
+ wire [8:0] mle_d_0, mle_d_1, mle_d_2, mle_d_3;
+ reg [8:0] mle_d_i;
+ wire mle_fifo_empty, mle_fifo_re;
+ wire [8:0] mle_fifo_d_o;
+
+ // TX between switch and MAC
+ wire [8:0] tx_sw_fifo_d0, tx_sw_fifo_d1, tx_sw_fifo_d2, tx_sw_fifo_du;
+ wire [NUM_PHYS-1:0] tx_mac_fifo_re;
+ wire tx_uc_fifo_re;
+ wire [NUM_PHYS-1:0] tx_sw_fifo_empty;
+ wire tx_sw_fifo_we; // for controller path
+ wire [2:0] tx_sw_mode0, tx_sw_mode1, tx_sw_mode2;
+ wire [2:0] tx_modeu;
+ wire [NUM_PHYS-1:0] tx_mac_done;
+ wire [10:0] tx0_byte_cnt, tx1_byte_cnt, tx2_byte_cnt;
+ wire [2:0] tx_src_sel0, tx_src_sel1, tx_src_sel2;
+
+ // TX between L3/L4 controller and MAC
+ wire tx_uc_fifo_empty, tx_mle_fifo_empty;
+ wire [8:0] tx_uc_fifo_d0, tx_mle_fifo_d0;
+
+ // 100 Mbit
+ wire [NUM_PHYS-1:0] mode_100Mbit;
+
+ // Controller Peripheral Address Decode and Select
+ wire mac_sel, pkt_filter_sel, mle_sel;
+ wire [1:0] mac_addr;
+ wire [15:0] pkt_filter_addr;
+
+ // FCS RX
+ wire [1:0] fcs_rx_addr0, fcs_rx_addr1, fcs_rx_addr2;
+ wire [7:0] fcs_rx_din0, fcs_rx_din1, fcs_rx_din2;
+ wire [7:0] fcs_rx_dout0, fcs_rx_dout1, fcs_rx_dout2;
+ wire [NUM_PHYS-1:0] fcs_rx_init, fcs_rx_enable;
+
+ // FCS TX
+ wire [1:0] fcs_tx_addr0, fcs_tx_addr1, fcs_tx_addr2;
+ wire [7:0] fcs_tx_din0, fcs_tx_din1, fcs_tx_din2;
+ wire [7:0] fcs_tx_dout0, fcs_tx_dout1, fcs_tx_dout2;
+ wire [NUM_PHYS-1:0] fcs_tx_init, fcs_tx_enable;
+
+ // IPv4
+ wire [NUM_PHYS-1:0] ipv4_pkt_start;
+ wire [NUM_PHYS-1:0] ipv4_pkt_complete;
+ wire [NUM_PHYS-1:0] ipv4_rx_keep;
+ wire [NUM_PHYS-1:0] ipv4_trigger_dst_addr;
+ wire ipv4_pkt_complete_c, ipv4_addr_match_c;
+
+ // UDP
+ wire udp_port_match_c;
+
+ // Network Debug & Metrics
+ wire [NUM_PHYS-1:0] mac_int;
+ wire [NUM_PHYS-1:0] mac_rx_active, mac_tx_active;
+ wire [NUM_PHYS-1:0] drop_rx0_active, drop_rx1_active, drop_rx2_active;
+ wire [NUM_PHYS-1:0] sync_rx0_active, sync_rx1_active, sync_rx2_active;
+ wire drop_rx0_active_u, sync_rx0_active_u;
+ wire [NUM_PHYS-1:0] rx_idle;
+ wire [NUM_PHYS-1:0] rx_mac_error;
+ wire [NUM_PHYS-1:0] rx_eop, rx_sop;
+ wire [NUM_PHYS-1:0] tx_eop, tx_sop, tx_error;
+
+ // Common Internal Memory Bus
+ wire[15:0] mem_addr;
+ reg [31:0] mem_d_i; // direction is from the point of view of the controller
+ wire [31:0] mem_d_o;
+ wire mem_we, mem_oe;
+ wire mem_tgt_ready, mem_tgt_ready_mac_0, mem_tgt_ready_mac_1;
+ wire [15:0] mac_0_d_o, mac_1_d_o, mac_2_d_o;
+ wire [15:0] mle_d_o;
+ wire [10:0] hfifo_d_o;
+
+ // half FIFO / Interface for Controller
+ wire hf_rx_fifo_int, hf_rx_fifo_int_acked;
+ wire hf_ptrs_sel, hf_rx_sel, hf_tx_sel;
+
+ // DPRAM PARAM data from controller
+ wire [10:0] param_phy0_addr, param_phy1_addr, param_phy2_addr;
+ wire [8:0] param_phy0_din, param_phy1_din, param_phy2_din;
+ wire [8:0] param_phy0_dout, param_phy1_dout, param_phy2_dout;
+ wire [8:0] param_ram_0_do, param_ram_1_do, param_ram_2_do;
+ wire param_phy0_ce, param_phy1_ce, param_phy2_ce;
+ wire param_phy0_we, param_phy1_we, param_phy2_we;
+ wire [NUM_PHYS-1:0] param_sel;
+
+ // MDIO controller and driver
+ wire mdio_cont_work_start, mdio_cont_work_done, mdio_cont_work_run;
+ wire [MDIO_ROM_ADDR_SZ-1:0] mdio_routine_addr;
+ wire mdio_done, mdo_oe;
+ wire mdo;
+ reg mdi;
+ wire [15:0] mdio_wd, mdio_rd; // write data, read data
+ wire mdio_rd_we;
+ wire mdio_ld, mdio_run;
+ wire mdio_rwn;
+ wire [4:0] mdio_reg_addr; // passed from mdio_cont -> mdio
+ wire [4:0] mdio_phy_addr;
+ wire [1:0] mdio_mux_sel;
+
+ // MDIO Data block
+ wire [MDIO_ROM_ADDR_SZ-1:0] mdio_rom_a;
+ wire [7:0] mdio_rom_d;
+ wire [4:0] mdio_reg_addr_set;
+ wire [7:0] mdio_w_data_h_set, mdio_w_data_l_set;
+
+ // Debug
+ wire [7:0] gpio_controller, gpio_ipv4;
+ reg evt_toggle;
+
+ // Fabric PLL
+ pll pll_0(
+ .areset(reset),
+ .inclk0(clk_i),
+ .c0(clk_25), // 25 MHz
+ .c1(clk_125), // 125 MHz
+ .locked(pll_locked));
+
+ assign reset = ~rstn;
+ assign cont_clk = clk_25;
+ assign phy1_clk = clk_25;
+ assign pclk = clk_125;
+
+ always @(posedge cont_clk, negedge rstn)
+ if (!rstn)
+ cnt_init <= 4'd0;
+ else if (cnt_init <= 4'd10)
+ cnt_init <= cnt_init + 1'b1;
+
+ // Place holder logic to remove reset properly per system requirements
+ // TODO: Review this since it probably should negate after PLL_LOCK
+ always @(posedge cont_clk, negedge rstn)
+ if (!rstn)
+ sys_rstn <= 1'b0;
+ else if (cnt_init >= 10'd9)
+ sys_rstn <= 1'b1;
+
+ // TODO: Review sequence and move to Controller control
+ assign phy0_rstn = sys_rstn;
+ assign phy1_rstn = pll_locked;
+ assign phy2_rstn = pll_locked;
+
+ // TODO: Fix this
+ assign phy_resetn = {pll_locked, pll_locked, pll_locked};
+
+ assign phy_int = {~phy2_intn, ~phy1_intn, ~phy0_intn};
+
+ // TODO: This will be replaced when the SPI master peripheral is ready
+ assign flash_d = 8'hab;
+ assign flash_seln = 1'b1;
+ assign flash_clk = cont_clk;
+
+ assign param_sel = 3'b000;
+
+ // TODO: Gate these when not in use
+ assign phy0_mdc = cont_clk;
+ assign phy1_mdc = cont_clk;
+ assign phy2_mdc = cont_clk;
+
+ assign phy2_gpio[0] = gpio_ipv4[0];
+ assign phy2_gpio[1] = gpio_ipv4[1];
+
+
+ // Bits 3:0 on the positive edge of RX_CLK and bits 7:4 on the negative edge of RX_CLK.
+ ddri rgmi_rx_0 (
+ .datain ({phy0_rx_ctl, phy0_rx_d}),
+ .inclock (phy0_rx_clk),
+ .dataout_h ({rx0_ctl_i[0],rx0_d_i[3:0]}),
+ .dataout_l ({rx0_ctl_i[1],rx0_d_i[7:4]})
+ );
+
+ ddri rgmi_rx_1 (
+ .datain ({phy1_rx_ctl, phy1_rx_d}),
+ .inclock (phy1_rx_clk),
+ .dataout_h ({rx1_ctl_i[0],rx1_d_i[3:0]}),
+ .dataout_l ({rx1_ctl_i[1],rx1_d_i[7:4]})
+ );
+
+ ddri rgmi_rx_2 (
+ .datain ({phy2_rx_ctl, phy2_rx_d}),
+ .inclock (phy2_rx_clk),
+ .dataout_h ({rx2_ctl_i[0],rx2_d_i[3:0]}),
+ .dataout_l ({rx2_ctl_i[1],rx2_d_i[7:4]})
+ );
+
+
+ // Simple Pipeline to Make Timing
+ always @(posedge phy0_rx_clk, negedge rstn)
+ if (!rstn) begin
+ rx0_d_i_m1 <= 8'h0;
+ rx0_d_i_m2 <= 8'h0;
+ rx0_d_i_m3 <= 8'h0;
+ rx0_d_i_m4 <= 8'h0;
+ end
+ else begin
+ rx0_d_i_m1 <= rx0_d_i;
+ rx0_d_i_m2 <= {rx0_d_i[7:4], rx0_d_i_m1[3:0]} ;
+ rx0_d_i_m3 <= rx0_d_i_m2;
+ rx0_d_i_m4 <= rx0_d_i_m3;
+ end
+
+ always @(posedge phy0_rx_clk, negedge rstn)
+ if (!rstn) begin
+ rx0_ctl_i_m1 <= 2'h0;
+ rx0_ctl_i_m2 <= 2'h0;
+ rx0_ctl_i_m3 <= 2'h0;
+ rx0_ctl_i_m4 <= 2'h0;
+ end
+ else begin
+ rx0_ctl_i_m1 <= rx0_ctl_i;
+ rx0_ctl_i_m2 <= {rx0_ctl_i[1],rx0_ctl_i_m1[0]};
+ rx0_ctl_i_m3 <= rx0_ctl_i_m2;
+ rx0_ctl_i_m4 <= rx0_ctl_i_m3;
+ end
+
+ // pipeline regs for PHY1
+ always @(posedge phy1_rx_clk, negedge rstn)
+ if (!rstn) begin
+ rx1_d_i_m1 <= 8'h0;
+ rx1_d_i_m2 <= 8'h0;
+ rx1_d_i_m3 <= 8'h0;
+ rx1_d_i_m4 <= 8'h0;
+ end
+ else begin
+ rx1_d_i_m1 <= rx1_d_i;
+ rx1_d_i_m2 <= {rx1_d_i[7:4], rx1_d_i_m1[3:0]} ;
+ rx1_d_i_m3 <= rx1_d_i_m2;
+ rx1_d_i_m4 <= rx1_d_i_m3;
+ end
+
+ always @(posedge phy1_rx_clk, negedge rstn)
+ if (!rstn) begin
+ rx1_ctl_i_m1 <= 2'h0;
+ rx1_ctl_i_m2 <= 2'h0;
+ rx1_ctl_i_m3 <= 2'h0;
+ rx1_ctl_i_m4 <= 2'h0;
+ end
+ else begin
+ rx1_ctl_i_m1 <= rx1_ctl_i;
+ rx1_ctl_i_m2 <= {rx1_ctl_i[1], rx1_ctl_i_m1[0]};
+ rx1_ctl_i_m3 <= rx1_ctl_i_m2;
+ rx1_ctl_i_m4 <= rx1_ctl_i_m3;
+ end
+
+`ifdef PHY2_PRESENT
+ // pipeline regs for PHY2
+ always @(posedge phy2_rx_clk, negedge rstn)
+ if (!rstn) begin
+ rx2_d_i_m1 <= 8'h0;
+ rx2_d_i_m2 <= 8'h0;
+ rx2_d_i_m3 <= 8'h0;
+ rx2_d_i_m4 <= 8'h0;
+ end
+ else begin
+ rx2_d_i_m1 <= rx2_d_i;
+ rx2_d_i_m2 <= {rx2_d_i[7:4], rx2_d_i_m1[3:0]} ;
+ rx2_d_i_m3 <= rx2_d_i_m2;
+ rx2_d_i_m4 <= rx2_d_i_m3;
+ end
+
+ always @(posedge phy2_rx_clk, negedge rstn)
+ if (!rstn) begin
+ rx2_ctl_i_m1 <= 2'h0;
+ rx2_ctl_i_m2 <= 2'h0;
+ rx2_ctl_i_m3 <= 2'h0;
+ rx2_ctl_i_m4 <= 2'h0;
+ end
+ else begin
+ rx2_ctl_i_m1 <= rx2_ctl_i;
+ rx2_ctl_i_m2 <= {rx2_ctl_i[1], rx2_ctl_i_m1[0]};
+ rx2_ctl_i_m3 <= rx2_ctl_i_m2;
+ rx2_ctl_i_m4 <= rx2_ctl_i_m3;
+ end
+`endif
+
+
+ /*
+ * main controller
+ *
+ */
+ controller #(.MDIO_ADDR_SZ(MDIO_ROM_ADDR_SZ), .NUM_PHYS(NUM_PHYS)) controller_0(
+ .rstn(sys_rstn),
+ .clk(cont_clk),
+ // status & errors
+ .phy_int(phy_int),
+ .mac_int(rx_mac_error),
+ // link status
+ .phy_up(phy_up),
+ // Memory Controller I/F
+ .mem_we(mem_we),
+ .mem_oe(mem_oe),
+ .mem_addr(mem_addr),
+ .mem_d_o(mem_d_o),
+ .mem_d_i(mem_d_i),
+ .mem_tgt_ready(mem_tgt_ready),
+ // Internal Device Selects
+ .mac_addr(mac_addr),
+ .pkt_filter_addr(pkt_filter_addr),
+ .pkt_filter_sel(pkt_filter_sel),
+ .mac_sel(mac_sel),
+ .mle_sel(mle_sel),
+ .hf_ptrs_sel(hf_ptrs_sel),
+ .hf_rx_sel(hf_rx_sel),
+ .hf_tx_sel(hf_tx_sel),
+ // half FIFO interface
+ .rx_fifo_int(hf_rx_fifo_int),
+ .rx_fifo_int_acked(hf_rx_fifo_int_acked),
+ .tx_fifo_empty(rx_uc_fifo_empty_u0),
+ // 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_we(mdio_rd_we),
+ .mdio_d_i(mdio_rd),
+ .mdio_mux_sel(mdio_mux_sel),
+ // mdio_data params
+ .mdio_phy_addr(mdio_phy_addr),
+ .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),
+ // Device Resets
+ .phy_resetn(),
+ .mac_reset(mac_reset),
+ // Debug
+ .gpio(gpio_controller)
+
+ );
+
+ assign mem_tgt_ready = mem_tgt_ready_mac_0 && mem_tgt_ready_mac_1;
+
+ // controller data mux
+ always @(*)
+ casex({ hf_tx_sel, hf_rx_sel, hf_ptrs_sel, mle_sel, mac_sel, mac_addr})
+ 7'b0000100: mem_d_i = {16'h0000, mac_0_d_o};
+ 7'b0000101: mem_d_i = {16'h0000, mac_1_d_o};
+ 7'b0000110: mem_d_i = {16'h0000, mac_2_d_o};
+ 7'b00010??: mem_d_i = {16'h0000, mle_d_o};
+ 7'b00100??: mem_d_i = {21'h0000, hfifo_d_o};
+ 7'b01000??: mem_d_i = {21'h0000, hfifo_d_o};
+ 7'b10000??: mem_d_i = {21'h0000, hfifo_d_o};
+ default: mem_d_i = 32'd0;
+ endcase
+
+ /*
+ * controller I/F FIFO
+ * FIFO side connects to network switch
+ * Switch/system perspective:
+ * RX: controller writes (data received into switch)
+ * TX: controller reads (data transmitted from switch)
+ */
+ half_fifo micro_fifo_0 (
+ .rstn( sys_rstn ),
+ .fifo_clk(pclk),
+ .uc_clk(cont_clk),
+ // controller interrupt support
+ .rx_fifo_int (hf_rx_fifo_int),
+ .rx_fifo_int_acked (hf_rx_fifo_int_acked),
+ // controller interface
+ .dpram_addr(mem_addr[10:0]),
+ .dpram_din(mem_d_o[10:0]),
+ .dpram_dout(hfifo_d_o),
+ .dpram_we(mem_we),
+ .dpram_oe(mem_oe),
+ .dpram_ptrs_sel(hf_ptrs_sel),
+ .dpram_tx_sel(hf_tx_sel),
+ .dpram_rx_sel(hf_rx_sel),
+ // TX: switch -> hfifo -> controller
+ .fifo_we(tx_sw_fifo_we),
+ .fifo_d_in(tx_sw_fifo_du),
+ // RX: controller -> hfifo -> switch
+ .fifo_re(rx_sw_fifo_re_u0),
+ .tx_byte_cnt(rxu_byte_cnt),
+ .fifo_d_out(rx_uc_fifo_d_u0),
+ .tx_empty(rx_uc_fifo_empty_u0)
+ );
+
+ mdio_cont #(.ADDR_SZ(MDIO_ROM_ADDR_SZ)) mdio_cont_0(
+ .rstn(sys_rstn),
+ .clk(cont_clk),
+ .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(mdio_rom_a),
+ .di(mdio_rom_d),
+ .reg_addr(mdio_reg_addr),
+ .dout(mdio_wd),
+ .ld(mdio_ld),
+ .rwn(mdio_rwn),
+ .done(mdio_done)
+ );
+
+ mdio_data_ti mdio_data_ti_0(
+ .ad(mdio_rom_a),
+ .reg_addr(mdio_reg_addr_set),
+ .data_in_h(mdio_w_data_h_set),
+ .data_in_l(mdio_w_data_l_set),
+ .d(mdio_rom_d),
+ .oe(1'b1)
+ );
+
+ mdio mdio_0(
+ .rstn(sys_rstn),
+ .mdc(cont_clk),
+ // MDIO
+ .mdi(mdi),
+ .mdo(mdo),
+ .mdo_oe(mdo_oe),
+ // mdio controller interface
+ .rwn(mdio_rwn),
+ .phy_addr(mdio_phy_addr),
+ .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)
+ );
+
+
+ /* MDIO mux and output enables, infer open drain for each mdio I/O */
+ always @(*) begin
+ case (mdio_mux_sel)
+ 2'b00: mdi = phy0_mdio;
+ 2'b01: mdi = phy1_mdio;
+ 2'b10: mdi = phy2_mdio;
+ endcase
+ end
+
+ // Support all PHYs
+ assign phy0_mdio = (mdo_oe && mdio_mux_sel == 2'b00) ? mdo : 1'bz;
+ assign phy1_mdio = (mdo_oe && mdio_mux_sel == 2'b01) ? mdo : 1'bz;
+ assign phy2_mdio = (mdo_oe && mdio_mux_sel == 2'b10) ? mdo : 1'bz;
+
+
+ always@(*)
+ case(mle_enable)
+ 3'b001: mle_d_i = mle_d_0;
+ 3'b010: mle_d_i = mle_d_1;
+ 3'b100: mle_d_i = mle_d_2;
+ default: mle_d_i = 'd0;
+ endcase
+
+
+ ml_engine #(.NUM_IF(NUM_ML_IF)) ml_engine_0(
+ .rstn(sys_rstn),
+ .clk(pclk),
+ // controller interface
+ .cont_clk(cont_clk),
+ .cont_sel(mle_sel),
+ .cont_we(mem_we),
+ .cont_addr(mem_addr),
+ .cont_d_i(mem_d_o[15:0]),
+ .cont_d_o(mle_d_o),
+ .cont_tgt_ready(),
+ // module interface
+ .evt_start(mle_evt_start),
+ .evt_active(mle_evt_active),
+ .enable(mle_enable),
+ .clk_e(1'b1),
+ .we(|mle_we),
+ .empty(mle_empty),
+ .d_i(mle_d_i),
+ // switch interface
+ .fifo_empty_o(mle_fifo_empty),
+ .fifo_re(mle_fifo_re),
+ .fifo_d_o(mle_fifo_d_o),
+ .byte_cnt(rx_mle_byte_cnt)
+ );
+
+ /*
+ * Controls the routing of data and transmit modes
+ */
+ switch switch_0(
+ .rstn(sys_rstn),
+ .clk(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_0u(rx_sf_fifo_d_0u),
+ .rx_d_10(rx_sf_fifo_d_10),
+ .rx_d_12(rx_sf_fifo_d_12),
+ .rx_d_20(rx_sf_fifo_d_20),
+ .rx_d_21(rx_sf_fifo_d_21),
+ .rx_d_u0(rx_uc_fifo_d_u0),
+ .rx_mle_fifo_d(mle_fifo_d_o),
+ // 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_0u(rx_sw_fifo_re_0u),
+ .rx_fifo_re_10(rx_sw_fifo_re_10),
+ .rx_fifo_re_12(rx_sw_fifo_re_12),
+ .rx_fifo_re_20(rx_sw_fifo_re_20),
+ .rx_fifo_re_21(rx_sw_fifo_re_21),
+ .rx_fifo_re_u0(rx_sw_fifo_re_u0),
+ .rx_fifo_re_mle(mle_fifo_re),
+ // 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_0u(rx_sf_fifo_empty_0u),
+ .rx_fifo_empty_10(rx_sf_fifo_empty_10),
+ .rx_fifo_empty_12(rx_sf_fifo_empty_12),
+ .rx_fifo_empty_20(rx_sf_fifo_empty_20),
+ .rx_fifo_empty_21(rx_sf_fifo_empty_21),
+ .rx_fifo_empty_u0(rx_uc_fifo_empty_u0),
+ .rx_fifo_empty_mle(mle_fifo_empty),
+ // Write done event
+ .rx_wr_done(rx_mac_wr_done),
+ // RX Byte Count
+ .rx0_byte_cnt(rx0_mac_byte_cnt),
+ .rx1_byte_cnt(rx1_mac_byte_cnt),
+ .rx2_byte_cnt(rx2_mac_byte_cnt),
+ .rxu_byte_cnt(rxu_byte_cnt),
+ .rx_mle_byte_cnt(rx_mle_byte_cnt),
+ // TX FIFO data output
+ .tx_d0(tx_sw_fifo_d0),
+ .tx_d1(tx_sw_fifo_d1),
+ .tx_d2(tx_sw_fifo_d2),
+ .tx_du(tx_sw_fifo_du),
+ // TX FIFO read enable
+ .tx_fifo_re(tx_mac_fifo_re),
+ .tx_fifo_we_u (tx_sw_fifo_we),
+ // TX FIFO Empty Flags
+ .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_modeu(tx_modeu),
+ // TX byte cnt
+ .tx0_byte_cnt(tx0_byte_cnt),
+ .tx1_byte_cnt(tx1_byte_cnt),
+ .tx2_byte_cnt(tx2_byte_cnt),
+ // TX Source Select
+ .tx0_src_sel(tx_src_sel0),
+ .tx1_src_sel(tx_src_sel1),
+ .tx2_src_sel(tx_src_sel2),
+ // TX state machine done flag
+ .tx_f(tx_mac_done),
+ .tx_custom(1'b0)
+ );
+
+ /*
+ *
+ * PHY0 IEEE 802.3 ETHERNET for Interface to 1000BASE-T LAN
+ *
+ */
+ mac_rgmii mac_0(
+ .rstn(sys_rstn),
+ .phy_resetn (phy_resetn[0]),
+ .rx_clk(phy0_rx_clk),
+ .tx_clk(pclk),
+ .tap_port (1'b0),
+ // controller interface
+ .cont_clk(cont_clk),
+ .cont_sel(mac_sel & mac_addr == 2'b00),
+ .cont_we(mem_we),
+ .cont_addr(mem_addr[7:0]),
+ .cont_d_i(mem_d_o[15:0]),
+ .cont_d_o(mac_0_d_o),
+ .cont_tgt_ready(mem_tgt_ready_mac_0),
+ // ML engine interface
+ .mle_active(mle_evt_active),
+ .mle_if_enable(mle_enable[0]),
+ .mle_if_oe(mle_oe),
+ .mle_if_we(mle_we[0]),
+ .mle_if_empty(mle_empty[0]),
+ .mle_if_d_o(mle_d_0),
+ // Line State
+ .fixed_speed(1'b1),
+ .mode_100Mbit(mode_100Mbit[0]),
+ .phy_up(phy_up[0]),
+ // Switch I/F
+ .tx_mode(tx_sw_mode0),
+ .tx_f(tx_mac_done[0]),
+ // RGMII data I/F
+ .rx_ctl({rx0_ctl_i[1],rx0_ctl_i_m1[0]}),
+ .rx_d({rx0_d_i[7:4], rx0_d_i_m1[3:0]}),
+ .tx_ctl(tx0_ctl),
+ .tx_d(tx0_d),
+ // RX FCS
+ .fcs_rx_init(fcs_rx_init[0]),
+ .fcs_rx_enable(fcs_rx_enable[0]),
+ .fcs_rx_addr(fcs_rx_addr0),
+ .fcs_rx_dout(fcs_rx_din0),
+ .fcs_rx_din(fcs_rx_dout0),
+ // TX FCS
+ .fcs_tx_init(fcs_tx_init[0]),
+ .fcs_tx_enable(fcs_tx_enable[0]),
+ .fcs_tx_addr(fcs_tx_addr0),
+ .fcs_tx_dout(fcs_tx_din0),
+ .fcs_tx_din(fcs_tx_dout0),
+ // MAC RX / FIFO Write
+ .rx_fifo_we(rx_mac_fifo_we[0]),
+ .rx_fifo_d(rx_mac_fifo_d0),
+ .rx_keep(rx_mac_keep[0]),
+ .rx_wr_done(rx_mac_wr_done[0]),
+ .rx_byte_cnt(rx0_mac_byte_cnt),
+ .rx_idle(rx_idle[0]),
+ .rx_error(rx_mac_error[0]),
+ // MAC TX / FIFO Read
+ .tx_byte_cnt_i(tx0_byte_cnt),
+ .tx_src_sel(tx_src_sel0),
+ .tx_fifo_re(tx_mac_fifo_re[0]),
+ .tx_fifo_d(tx_sw_fifo_d0),
+ .tx_fifo_empty(tx_sw_fifo_empty[0]),
+ // Alternate TX Port (uC)
+ .tx_uc_fifo_empty(tx_uc_fifo_empty),
+ .tx_uc_fifo_d(tx_uc_fifo_d0),
+ // Alternate TX Port (MLE)
+ .tx_mle_fifo_empty(tx_mle_fifo_empty),
+ .tx_mle_fifo_d(tx_mle_fifo_d0),
+ // Packet Filter
+ .rx_sample(rx_sample[0]),
+ .ipv4_pkt_start(ipv4_pkt_start[0]),
+ .trigger(),
+ .rx_ctl_m1(rx0_ctl_m1),
+ .rx_ctl_m2(rx0_ctl_m2),
+ .rx_ctl_m3(rx0_ctl_m3),
+ .rx_ctl_m4(rx0_ctl_m4),
+ .rx_d_m1(rx0_d_m1),
+ .rx_d_m2(rx0_d_m2),
+ .rx_d_m3(rx0_d_m3),
+ .rx_d_m4(rx0_d_m4),
+ // Param RAM
+ .dpr_ad(param_phy0_addr),
+ .dpr_we(param_phy0_we),
+ .dpr_ce(param_phy0_ce),
+ .dpr_di(param_phy0_din),
+ .dpr_do(param_phy0_dout),
+ // Metrics and Interrupts
+ .rx_enet_bcast(rx_enet_bcast[0]),
+ .rx_ipv4_arp(rx_ipv4_arp[0]),
+ .rx_l3_proto(),
+ .rx_pkt_length(),
+ .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]),
+ .rx_active(mac_rx_active[0]),
+ .tx_active(mac_tx_active[0])
+ );
+
+
+ ipv4_rx ipv4_rx_0(
+ .rstn(sys_rstn),
+ .clk(phy0_rx_clk),
+ // control
+ .phy_resetn (phy_resetn[0]),
+ .phy_up(phy_up[0]),
+ // packet data
+ .pkt_start(ipv4_pkt_start[0]),
+ .rx_sample(rx_sample[0]),
+ .rx_eop(rx_eop[0]),
+ .rx_data_m1(rx0_d_m1),
+ .rx_data_m2(rx0_d_m2),
+ .rx_data_m3(rx0_d_m3),
+ .rx_data_m4(rx0_d_m4),
+ // flags
+ .pkt_complete(ipv4_pkt_complete[0]),
+ .trigger_src_addr(),
+ .trigger_dst_addr(ipv4_trigger_dst_addr[0]),
+ .keep(ipv4_rx_keep[0])
+ );
+
+ udp_rx udp_rx_0(
+ .rstn(sys_rstn),
+ .clk(phy0_rx_clk),
+ // control
+ .phy_resetn (phy_resetn[0]),
+ .phy_up(phy_up[0]),
+ // packet data
+ .pkt_start(ipv4_trigger_dst_addr[0]),
+ .rx_sample(rx_sample[0]),
+ .rx_eop(rx_eop[0]),
+ .rx_data_m1(rx0_d_m1),
+ .rx_data_m2(rx0_d_m2),
+ .rx_data_m3(rx0_d_m3),
+ .rx_data_m4(rx0_d_m4),
+ // flags
+ .pkt_complete(),
+ .trigger_src_port(),
+ .trigger_dst_port(trigger[0]),
+ .keep()
+ );
+
+
+ // PHY0 MAC -> PHY1
+ pkt_filter pkt_filter_01(
+ .rstn(sys_rstn),
+ .clk(phy0_rx_clk),
+ // input for programming
+ .prgclk(cont_clk),
+ .sel(pkt_filter_sel && pkt_filter_addr == 16'h0001),
+ .we(mem_we),
+ .addr(mem_addr[2:0]),
+ .d_i(mem_d_o),
+ .d_o(),
+ // registered data
+ .rx_d_m1(rx0_d_m1),
+ .rx_d_m2(rx0_d_m2),
+ .rx_d_m3(rx0_d_m3),
+ .rx_d_m4(rx0_d_m4),
+ // filter
+ .new_frame (rx_sop[0]),
+ .block(1'b0),
+ .invert(1'b1),
+ .trigger(rx_mac_keep[0]),
+ .keep(rx_pf_keep_01)
+ );
+
+ drop_fifo drop_fifo_01(
+ .rstn(sys_rstn),
+ .phy_up(phy_up[0]),
+ .rx_clk(phy0_rx_clk),
+ .tx_clk(pclk),
+ .enable(1'b1), // ipv4_rx_keep[0]
+ // control
+ .keep (rx_pf_keep_01),
+ .passthrough(1'b0),
+ // input
+ .we_in(rx_mac_fifo_we[0]),
+ .wr_done(rx_mac_wr_done[0]),
+ .rx_idle(rx_idle[0]),
+ .rx_error(rx_mac_error[0]),
+ .d_in(rx_mac_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(sys_rstn),
+ .clk (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])
+ );
+
+
+`ifdef PHY2_PRESENT
+ // PHY0 MAC -> PHY1
+ pkt_filter pkt_filter_02(
+ .rstn(sys_rstn),
+ .clk(phy0_rx_clk),
+ // input for programming
+ .prgclk(cont_clk),
+ .sel(pkt_filter_sel && pkt_filter_addr == 16'h0002),
+ .we(mem_we),
+ .addr(mem_addr[2:0]),
+ .d_i(mem_d_o),
+ .d_o(),
+ // registered data
+ .rx_d_m1(rx0_d_m1),
+ .rx_d_m2(rx0_d_m2),
+ .rx_d_m3(rx0_d_m3),
+ .rx_d_m4(rx0_d_m4),
+ // filter
+ .new_frame (rx_sop[0]),
+ .block(1'b0),
+ .invert(1'b1),
+ .trigger(rx_mac_keep[0]),
+ .keep(rx_pf_keep_02)
+ );
+
+ drop_fifo drop_fifo_02(
+ .rstn(sys_rstn),
+ .phy_up(phy_up[0]),
+ .rx_clk(phy0_rx_clk),
+ .tx_clk(pclk),
+ .enable(1'b1), // ipv4_rx_keep[0]
+ // control
+ .keep (rx_pf_keep_02),
+ .passthrough(1'b0),
+ // input
+ .we_in(rx_mac_fifo_we[0]),
+ .wr_done(rx_mac_wr_done[0]),
+ .rx_idle(rx_idle[0]),
+ .rx_error(rx_mac_error[0]),
+ .d_in(rx_mac_fifo_d0),
+ // output
+ .we_out(rx_df_fifo_we_02),
+ .d_out(rx_df_fifo_d_02),
+ // debug
+ .active(drop_rx0_active[2])
+ );
+
+ sync_fifo sync_fifo_rx_02(
+ .rstn(sys_rstn),
+ .clk (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(),
+ .reset_ptrs(1'b0),
+ // debug
+ .active(sync_rx0_active[2])
+ );
+`endif
+
+ ipv4_rx_c #(.IP_DST_MATCH_4(100)) ipv4_rx_c_0(
+ .rstn(sys_rstn),
+ .clk(phy0_rx_clk),
+ // control
+ .phy_up(phy_up[0]),
+ // packet data
+ .pkt_start(ipv4_pkt_start[0]),
+ .rx_sample(rx_sample[0]),
+ .rx_eop(rx_eop[0]),
+ .rx_data_m1(rx0_d_m1),
+ .rx_data_m2(rx0_d_m2),
+ .rx_data_m3(rx0_d_m3),
+ .rx_data_m4(rx0_d_m4),
+ // flags
+ .pkt_complete(ipv4_pkt_complete_c),
+ .ip_addr_match(ipv4_addr_match_c)
+ );
+
+ udp_rx_c udp_rx_c_0(
+ .rstn(sys_rstn),
+ .clk(phy0_rx_clk),
+ // control
+ .phy_up(phy_up[0]),
+ // packet data
+ .rx_sample(1'b1),
+ .pkt_start(ipv4_trigger_dst_addr[0]),
+ .rx_eop(rx_eop[0]),
+ .rx_data_m1(rx0_d_m1),
+ .rx_data_m2(rx0_d_m2),
+ .rx_data_m3(rx0_d_m3),
+ .rx_data_m4(rx0_d_m4),
+ // flags
+ .pkt_complete(),
+ .udp_port_match(udp_port_match_c)
+ );
+
+
+ drop_fifo drop_fifo_0u(
+ .rstn(sys_rstn),
+ .phy_up(phy_up[0]),
+ .rx_clk(phy0_rx_clk),
+ .tx_clk(pclk),
+ .enable(ipv4_addr_match_c),
+ // control
+ .keep (udp_port_match_c),
+ .passthrough(1'b0),
+ // input
+ .we_in(rx_mac_fifo_we[0]),
+ .wr_done(rx_mac_wr_done[0]),
+ .rx_idle(rx_idle[0]),
+ .rx_error(rx_mac_error[0]),
+ .d_in(rx_mac_fifo_d0),
+ // output
+ .we_out(rx_df_fifo_we_0u),
+ .d_out(rx_df_fifo_d_0u),
+ .active(drop_rx0_active_u)
+ );
+
+ sync_fifo sync_fifo_rx_0u(
+ .rstn(sys_rstn),
+ .clk (pclk),
+ // input
+ .we (rx_df_fifo_we_0u),
+ .d_in (rx_df_fifo_d_0u),
+ // output
+ .re (rx_sw_fifo_re_0u),
+ .d_out(rx_sf_fifo_d_0u),
+ .empty(rx_sf_fifo_empty_0u),
+ .almost_full(rx_sf_almost_full_0u),
+ .reset_ptrs(1'b0),
+ // debug
+ .active(sync_rx0_active_u )
+ );
+
+ dpram_inf #(.ADDR_WIDTH(10), .DPRAM_INIT("param_ram_0.txt")) param_ram_0(
+ .rstn(sys_rstn),
+ // Port A
+ .a_clk(cont_clk),
+ .a_clk_e(param_sel[0]),
+ .a_we(1'b0),
+ .a_oe(mem_oe),
+ .a_addr(mem_addr[9:0]),
+ .a_din(mem_d_o[8:0]),
+ .a_dout(param_ram_0_do),
+ // Port B
+ .b_clk(pclk),
+ .b_clk_e(param_phy0_ce),
+ .b_we(param_phy0_we),
+ .b_oe(1'b1),
+ .b_addr(param_phy0_addr[9:0]),
+ .b_din(param_phy0_dout),
+ .b_dout(param_phy0_din)
+ );
+
+ fcs fcs_rx_0(
+ .rstn(sys_rstn),
+ .clk(phy0_rx_clk),
+ .init(fcs_rx_init[0]),
+ .enable(fcs_rx_enable[0]),
+ .addr(fcs_rx_addr0),
+ .din(fcs_rx_din0),
+ .dout(fcs_rx_dout0)
+ );
+
+ fcs fcs_tx_0(
+ .rstn(sys_rstn),
+ .clk(pclk),
+ .init(fcs_tx_init[0]),
+ .enable(fcs_tx_enable[0]),
+ .addr(fcs_tx_addr0),
+ .din(fcs_tx_din0),
+ .dout(fcs_tx_dout0)
+ );
+
+ ipv4_tx_c ipv4_tx_c_0(
+ .rstn(sys_rstn),
+ .phy_resetn(phy_resetn[0]),
+ .clk(pclk),
+ // Control Interface
+ .cont_clk(cont_clk),
+ .cont_sel(ipv4_tx_c_sel),
+ .cont_we(mem_we),
+ .cont_addr(mem_addr[7:0]),
+ .cont_d_i(mem_d_o[15:0]),
+ .cont_d_o(),
+ // Line State
+ .mode_100Mbit(mode_100Mbit[0]),
+ .phy_up(phy_up[0]),
+ // Switch I/F
+ .tx_mode(tx_sw_mode0),
+ .tx_src_sel(tx_src_sel0),
+ .byte_cnt_i(tx0_byte_cnt),
+ // MAC Interface
+ .fifo_re_i(tx_mac_fifo_re[0]),
+ .fifo_empty_o(tx_uc_fifo_empty),
+ .fifo_d_o(tx_uc_fifo_d0),
+ // Debug
+ .gpio(gpio_ipv4)
+ );
+
+ ipv4_tx_mle ipv4_tx_mle_0(
+ .rstn(sys_rstn),
+ .phy_resetn(phy_resetn[0]),
+ .clk(pclk),
+ // Control Interface
+ .cont_clk(cont_clk),
+ .cont_sel(ipv4_tx_mle_sel),
+ .cont_we(mem_we),
+ .cont_addr(mem_addr[7:0]),
+ .cont_d_i(mem_d_o[15:0]),
+ .cont_d_o(),
+ // Line State
+ .mode_100Mbit(mode_100Mbit[0]),
+ .phy_up(phy_up[0]),
+ // Switch I/F
+ .tx_mode(tx_sw_mode0),
+ .tx_src_sel(tx_src_sel0),
+ .byte_cnt_i(tx0_byte_cnt),
+ // MAC Interface
+ .fifo_re_i(tx_mac_fifo_re[0]),
+ .fifo_empty_o(tx_mle_fifo_empty),
+ .fifo_d_o(tx_mle_fifo_d0),
+ // Debug
+ .gpio()
+ );
+
+
+ /*
+ *
+ * PHY1 IEEE 802.3 ETHERNET for Interface to 1000BASE-T LAN
+ *
+ */
+ mac_rgmii mac_1(
+ .rstn(sys_rstn),
+ .phy_resetn (phy_resetn[1]),
+ .rx_clk(phy1_rx_clk),
+ .tx_clk(pclk),
+ .tap_port (1'b0),
+ // Control Interface
+ .cont_clk(cont_clk),
+ .cont_sel(mac_sel & mac_addr == 2'b01),
+ .cont_we(mem_we),
+ .cont_addr(mem_addr[7:0]),
+ .cont_d_i(mem_d_o[15:0]),
+ .cont_d_o(mac_1_d_o),
+ .cont_tgt_ready(mem_tgt_ready_mac_1),
+ // ML engine interface
+ .mle_active(mle_evt_active),
+ .mle_if_enable(mle_enable[1]),
+ .mle_if_oe(mle_oe),
+ .mle_if_we(mle_we[1]),
+ .mle_if_empty(mle_empty[1]),
+ .mle_if_d_o(mle_d_1),
+ // Line State
+ .fixed_speed(1'b1),
+ .mode_100Mbit(mode_100Mbit[1]),
+ .phy_up(phy_up[1]),
+ // Switch I/F
+ .tx_mode(tx_sw_mode1),
+ .tx_f(tx_mac_done[1]),
+ // RGMII data I/F
+ .rx_ctl({rx1_ctl_i[1],rx1_ctl_i_m1[0]}),
+ .rx_d({rx1_d_i[7:4], rx1_d_i_m1[3:0]}),
+ .tx_ctl(tx1_ctl),
+ .tx_d(tx1_d),
+ // RX FCS
+ .fcs_rx_init(fcs_rx_init[1]),
+ .fcs_rx_enable(fcs_rx_enable[1]),
+ .fcs_rx_addr(fcs_rx_addr1),
+ .fcs_rx_dout(fcs_rx_din1),
+ .fcs_rx_din(fcs_rx_dout1),
+ // TX FCS
+ .fcs_tx_init(fcs_tx_init[1]),
+ .fcs_tx_enable(fcs_tx_enable[1]),
+ .fcs_tx_addr(fcs_tx_addr1),
+ .fcs_tx_dout(fcs_tx_din1),
+ .fcs_tx_din(fcs_tx_dout1),
+ // MAC RX / FIFO Write
+ .rx_fifo_we(rx_mac_fifo_we[1]),
+ .rx_fifo_d(rx_mac_fifo_d1),
+ .rx_keep(rx_mac_keep[1]),
+ .rx_wr_done(rx_mac_wr_done[1]),
+ .rx_byte_cnt(rx1_mac_byte_cnt),
+ .rx_idle(rx_idle[1]),
+ .rx_error(rx_mac_error[1]),
+ // MAC TX / FIFO Read
+ .tx_byte_cnt_i(tx1_byte_cnt),
+ .tx_src_sel(tx_src_sel1),
+ .tx_fifo_re(tx_mac_fifo_re[1]),
+ .tx_fifo_d(tx_sw_fifo_d1),
+ .tx_fifo_empty(tx_sw_fifo_empty[1]),
+ // Alternate TX Port
+ .tx_uc_fifo_empty(1'b1), // tie off to disable port
+ .tx_uc_fifo_d(9'd0),
+ .tx_mle_fifo_empty(1'b1),
+ .tx_mle_fifo_d(9'd0),
+ // Packet Filter
+ .rx_sample(rx_sample[1]),
+ .ipv4_pkt_start(ipv4_pkt_start[1]),
+ .trigger(),
+ .rx_ctl_m1(rx1_ctl_m1),
+ .rx_ctl_m2(rx1_ctl_m2),
+ .rx_ctl_m3(rx1_ctl_m3),
+ .rx_ctl_m4(rx1_ctl_m4),
+ .rx_d_m1(rx1_d_m1),
+ .rx_d_m2(rx1_d_m2),
+ .rx_d_m3(rx1_d_m3),
+ .rx_d_m4(rx1_d_m4),
+ // Param RAM
+ .dpr_ad(param_phy1_addr),
+ .dpr_we(param_phy1_we),
+ .dpr_ce(param_phy1_ce),
+ .dpr_di(param_phy1_din),
+ .dpr_do(param_phy1_dout),
+ // Metrics and Interrupts
+ .rx_enet_bcast(rx_enet_bcast[1]),
+ .rx_ipv4_arp(rx_ipv4_arp[1]),
+ .rx_l3_proto(),
+ .rx_pkt_length(),
+ .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]),
+ .rx_active(mac_rx_active[1]),
+ .tx_active(mac_tx_active[1])
+ );
+
+ ipv4_rx ipv4_rx_1(
+ .rstn(sys_rstn),
+ .clk(phy1_rx_clk),
+ // control
+ .phy_resetn (phy_resetn[1]),
+ .phy_up(phy_up[1]),
+ // packet data
+ .pkt_start(ipv4_pkt_start[1]),
+ .rx_sample(rx_sample[1]),
+ .rx_eop(rx_eop[1]),
+ .rx_data_m1(rx1_d_m1),
+ .rx_data_m2(rx1_d_m2),
+ .rx_data_m3(rx1_d_m3),
+ .rx_data_m4(rx1_d_m4),
+ // flags
+ .pkt_complete(ipv4_pkt_complete[1]),
+ .trigger_src_addr(),
+ .trigger_dst_addr(ipv4_trigger_dst_addr[1]),
+ .keep(ipv4_rx_keep[1])
+ );
+
+ udp_rx udp_rx_1(
+ .rstn(sys_rstn),
+ .clk(phy1_rx_clk),
+ // control
+ .phy_resetn (phy_resetn[1]),
+ .phy_up(phy_up[1]),
+ // packet data
+ .pkt_start(ipv4_trigger_dst_addr[1]),
+ .rx_sample(rx_sample[1]),
+ .rx_eop(rx_eop[1]),
+ .rx_data_m1(rx1_d_m1),
+ .rx_data_m2(rx1_d_m2),
+ .rx_data_m3(rx1_d_m3),
+ .rx_data_m4(rx1_d_m4),
+ // flags
+ .pkt_complete(),
+ .trigger_src_port(),
+ .trigger_dst_port(trigger[1]),
+ .keep()
+ );
+
+
+ // PHY1 MAC -> PHY 0
+ pkt_filter pkt_filter_10(
+ .rstn(sys_rstn),
+ .clk(phy1_rx_clk),
+ // input for programming
+ .prgclk(cont_clk),
+ .sel(pkt_filter_sel && pkt_filter_addr == 16'h1000),
+ .we(mem_we),
+ .addr(mem_addr[2:0]),
+ .d_i(mem_d_o),
+ .d_o(),
+ // registered data
+ .rx_d_m1(rx1_d_m1),
+ .rx_d_m2(rx1_d_m2),
+ .rx_d_m3(rx1_d_m3),
+ .rx_d_m4(rx1_d_m4),
+ // filter
+ .new_frame (rx_sop[1]),
+ .block(1'b0),
+ .invert(1'b1),
+ .trigger(rx_mac_keep[1]),
+ .keep(rx_pf_keep_10)
+ );
+
+ drop_fifo drop_fifo_10(
+ .rstn(sys_rstn),
+ .phy_up(phy_up[1]),
+ .rx_clk(phy1_rx_clk),
+ .tx_clk(pclk),
+ .enable(1'b1), // ipv4_rx_keep[1]
+ // control
+ .keep (rx_pf_keep_10),
+ .passthrough(1'b0),
+ // input
+ .we_in(rx_mac_fifo_we[1]),
+ .wr_done(rx_mac_wr_done[1]),
+ .rx_idle(rx_idle[1]),
+ .rx_error(rx_mac_error[1]),
+ .d_in(rx_mac_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(sys_rstn),
+ .clk (pclk),
+ // input
+ .we (rx_df_fifo_we_10 & phy_up[0]),
+ .d_in (rx_df_fifo_d_10),
+ // output
+ .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])
+ );
+
+`ifdef PHY2_PRESENT
+
+ // PHY1 MAC -> PHY2
+ pkt_filter pkt_filter_12(
+ .rstn(sys_rstn),
+ .clk(phy1_rx_clk),
+ // input for programming
+ .prgclk(cont_clk),
+ .sel(pkt_filter_sel && pkt_filter_addr == 16'h1002),
+ .we(mem_we),
+ .addr(mem_addr[2:0]),
+ .d_i(mem_d_o),
+ .d_o(),
+ // registered data
+ .rx_d_m1(rx1_d_m1),
+ .rx_d_m2(rx1_d_m2),
+ .rx_d_m3(rx1_d_m3),
+ .rx_d_m4(rx1_d_m4),
+ // filter
+ .new_frame (rx_sop[1]),
+ .block(1'b0),
+ .invert(1'b1),
+ .trigger(rx_mac_keep[1]),
+ .keep(rx_pf_keep_12)
+ );
+
+ drop_fifo drop_fifo_12(
+ .rstn(sys_rstn),
+ .phy_up(phy_up[1]),
+ .rx_clk(phy1_rx_clk),
+ .tx_clk(pclk),
+ .enable(1'b1), // ipv4_rx_keep[1]
+ // control
+ .keep (rx_pf_keep_12),
+ .passthrough(1'b0),
+ // input
+ .we_in(rx_mac_fifo_we[1]),
+ .wr_done(rx_mac_wr_done[1]),
+ .rx_idle(rx_idle[1]),
+ .rx_error(rx_mac_error[1]),
+ .d_in(rx_mac_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(sys_rstn),
+ .clk (pclk),
+ // input
+ .we (rx_df_fifo_we_12 & phy_up[2]),
+ .d_in (rx_df_fifo_d_12),
+ // output
+ .re (rx_sw_fifo_re_12),
+ .d_out(rx_sf_fifo_d_12),
+ .empty(rx_sf_fifo_empty_12),
+ .almost_full(),
+ .reset_ptrs(1'b0),
+ // debug
+ .active(sync_rx1_active[2])
+ );
+
+`endif
+
+ dpram_inf #(.ADDR_WIDTH(10), .DPRAM_INIT("param_ram_1.txt")) param_ram_1(
+ .rstn(sys_rstn),
+ // Port A
+ .a_clk(cont_clk),
+ .a_clk_e(param_sel[1]),
+ .a_we(1'b0),
+ .a_oe(mem_oe),
+ .a_addr(mem_addr[9:0]),
+ .a_din(mem_d_o[8:0]),
+ .a_dout(param_ram_1_do),
+ // Port B
+ .b_clk(pclk),
+ .b_clk_e(param_phy1_ce),
+ .b_we(param_phy1_we),
+ .b_oe(1'b1),
+ .b_addr(param_phy1_addr[9:0]),
+ .b_din(param_phy1_dout),
+ .b_dout(param_phy1_din)
+ );
+
+ fcs fcs_rx_1(
+ .rstn(sys_rstn),
+ .clk(phy1_rx_clk),
+ .init(fcs_rx_init[1]),
+ .enable(fcs_rx_enable[1]),
+ .addr(fcs_rx_addr1),
+ .din(fcs_rx_din1),
+ .dout(fcs_rx_dout1)
+ );
+
+ fcs fcs_tx_1(
+ .rstn(sys_rstn),
+ .clk(pclk),
+ .init(fcs_tx_init[1]),
+ .enable(fcs_tx_enable[1]),
+ .addr(fcs_tx_addr1),
+ .din(fcs_tx_din1),
+ .dout(fcs_tx_dout1)
+ );
+
+`ifdef PHY2_PRESENT
+ /*
+ *
+ * PHY2 IEEE 802.3 ETHERNET for Interface to 1000BASE-T LAN
+ *
+ */
+ mac_rgmii mac_2(
+ .rstn(sys_rstn),
+ .phy_resetn (phy_resetn[2]),
+ .rx_clk(phy2_rx_clk),
+ .tx_clk(pclk),
+ .tap_port (1'b0),
+ // Control Interface
+ .cont_clk(cont_clk),
+ .cont_sel(mac_sel & mac_addr == 2'b10),
+ .cont_we(mem_we),
+ .cont_addr(mem_addr[7:0]),
+ .cont_d_i(mem_d_o[15:0]),
+ .cont_d_o(mac_2_d_o),
+ .cont_tgt_ready(mem_tgt_ready_mac_2),
+ // ML engine interface
+ .mle_active(mle_evt_active),
+ .mle_if_enable(mle_enable[2]),
+ .mle_if_oe(mle_oe),
+ .mle_if_we(mle_we[2]),
+ .mle_if_empty(mle_empty[2]),
+ .mle_if_d_o(mle_d_2),
+ // Line State
+ .fixed_speed(1'b1),
+ .mode_100Mbit(mode_100Mbit[2]),
+ .phy_up(phy_up[2]),
+ // Switch I/F
+ .tx_mode(tx_sw_mode2),
+ .tx_f(tx_mac_done[2]),
+ // RGMII data I/F
+ .rx_ctl({rx2_ctl_i[1],rx2_ctl_i_m1[0]}),
+ .rx_d({rx2_d_i[7:4], rx2_d_i_m1[3:0]}),
+ .tx_ctl(tx2_ctl),
+ .tx_d(tx2_d),
+ // RX FCS
+ .fcs_rx_init(fcs_rx_init[2]),
+ .fcs_rx_enable(fcs_rx_enable[2]),
+ .fcs_rx_addr(fcs_rx_addr2),
+ .fcs_rx_dout(fcs_rx_din2),
+ .fcs_rx_din(fcs_rx_dout2),
+ // TX FCS
+ .fcs_tx_init(fcs_tx_init[2]),
+ .fcs_tx_enable(fcs_tx_enable[2]),
+ .fcs_tx_addr(fcs_tx_addr2),
+ .fcs_tx_dout(fcs_tx_din2),
+ .fcs_tx_din(fcs_tx_dout2),
+ // MAC RX / FIFO Write
+ .rx_fifo_we(rx_mac_fifo_we[2]),
+ .rx_fifo_d(rx_mac_fifo_d2),
+ .rx_keep(rx_mac_keep[2]),
+ .rx_wr_done(rx_mac_wr_done[2]),
+ .rx_byte_cnt(rx2_mac_byte_cnt),
+ .rx_idle(rx_idle[2]),
+ .rx_error(rx_mac_error[2]),
+ // MAC TX / FIFO Read
+ .tx_byte_cnt_i(tx2_byte_cnt),
+ .tx_src_sel(tx_src_sel2),
+ .tx_fifo_re(tx_mac_fifo_re[2]),
+ .tx_fifo_d(tx_sw_fifo_d2),
+ .tx_fifo_empty(tx_sw_fifo_empty[2]),
+ // Alternate TX Port
+ .tx_uc_fifo_empty(1'b1), // tie off to disable port
+ .tx_uc_fifo_d(9'd0),
+ .tx_mle_fifo_empty(1'b1),
+ .tx_mle_fifo_d(9'd0),
+ // Packet Filter
+ .rx_sample(rx_sample[2]),
+ .ipv4_pkt_start(ipv4_pkt_start[2]),
+ .trigger(),
+ .rx_ctl_m1(rx2_ctl_m1),
+ .rx_ctl_m2(rx2_ctl_m2),
+ .rx_ctl_m3(rx2_ctl_m3),
+ .rx_ctl_m4(rx2_ctl_m4),
+ .rx_d_m1(rx2_d_m1),
+ .rx_d_m2(rx2_d_m2),
+ .rx_d_m3(rx2_d_m3),
+ .rx_d_m4(rx2_d_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
+ .rx_enet_bcast(rx_enet_bcast[2]),
+ .rx_ipv4_arp(rx_ipv4_arp[2]),
+ .rx_l3_proto(),
+ .rx_pkt_length(),
+ .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]),
+ .rx_active(mac_rx_active[2]),
+ .tx_active(mac_tx_active[2])
+ );
+
+ ipv4_rx ipv4_rx_2(
+ .rstn(sys_rstn),
+ .clk(phy2_rx_clk),
+ // control
+ .phy_resetn (phy_resetn[2]),
+ .phy_up(phy_up[2]),
+ // packet data
+ .pkt_start(ipv4_pkt_start[2]),
+ .rx_sample(rx_sample[2]),
+ .rx_eop(rx_eop[2]),
+ .rx_data_m1(rx2_d_m1),
+ .rx_data_m2(rx2_d_m2),
+ .rx_data_m3(rx2_d_m3),
+ .rx_data_m4(rx2_d_m4),
+ // flags
+ .pkt_complete(ipv4_pkt_complete[2]),
+ .trigger_src_addr(),
+ .trigger_dst_addr(ipv4_trigger_dst_addr[2]),
+ .keep(ipv4_rx_keep[2])
+ );
+
+ udp_rx udp_rx_2(
+ .rstn(sys_rstn),
+ .clk(phy2_rx_clk),
+ // control
+ .phy_resetn (phy_resetn[2]),
+ .phy_up(phy_up[2]),
+ // packet data
+ .pkt_start(ipv4_trigger_dst_addr[2]),
+ .rx_sample(rx_sample[2]),
+ .rx_eop(rx_eop[2]),
+ .rx_data_m1(rx2_d_m1),
+ .rx_data_m2(rx2_d_m2),
+ .rx_data_m3(rx2_d_m3),
+ .rx_data_m4(rx2_d_m4),
+ // flags
+ .pkt_complete(),
+ .trigger_src_port(),
+ .trigger_dst_port(trigger[2]),
+ .keep()
+ );
+
+
+ // PHY2 MAC -> PHY 0
+ pkt_filter pkt_filter_20(
+ .rstn(sys_rstn),
+ .clk(phy2_rx_clk),
+ // input for programming
+ .prgclk(cont_clk),
+ .sel(pkt_filter_sel && pkt_filter_addr == 16'h2000),
+ .we(mem_we),
+ .addr(mem_addr[2:0]),
+ .d_i(mem_d_o),
+ .d_o(),
+ // registered data
+ .rx_d_m1(rx2_d_m1),
+ .rx_d_m2(rx2_d_m2),
+ .rx_d_m3(rx2_d_m3),
+ .rx_d_m4(rx2_d_m4),
+ // filter
+ .new_frame (rx_sop[2]),
+ .block(1'b0),
+ .invert(1'b1),
+ .trigger(rx_mac_keep[2]),
+ .keep(rx_pf_keep_20)
+ );
+
+ drop_fifo drop_fifo_20(
+ .rstn(sys_rstn),
+ .phy_up(phy_up[2]),
+ .rx_clk(phy2_rx_clk),
+ .tx_clk(pclk),
+ .enable(1'b1), // ipv4_rx_keep[2]
+ // control
+ .keep (rx_pf_keep_20),
+ .passthrough(1'b0),
+ // input
+ .we_in(rx_mac_fifo_we[2]),
+ .wr_done(rx_mac_wr_done[2]),
+ .rx_idle(rx_idle[2]),
+ .rx_error(rx_mac_error[2]),
+ .d_in(rx_mac_fifo_d2),
+ // output
+ .we_out(rx_df_fifo_we_20),
+ .d_out(rx_df_fifo_d_20),
+ // debug
+ .active(drop_rx2_active[0])
+ );
+
+ sync_fifo sync_fifo_rx_20(
+ .rstn(sys_rstn),
+ .clk (pclk),
+ // input
+ .we (rx_df_fifo_we_20 & phy_up[0]),
+ .d_in (rx_df_fifo_d_20),
+ // output
+ .re (rx_sw_fifo_re_20),
+ .d_out(rx_sf_fifo_d_20),
+ .empty(rx_sf_fifo_empty_20),
+ .almost_full(),
+ .reset_ptrs(1'b0),
+ // debug
+ .active(sync_rx2_active[0])
+ );
+
+
+ // PHY1 MAC -> PHY2
+ pkt_filter pkt_filter_21(
+ .rstn(sys_rstn),
+ .clk(phy2_rx_clk),
+ // input for programming
+ .prgclk(cont_clk),
+ .sel(pkt_filter_sel && pkt_filter_addr == 16'h2001),
+ .we(mem_we),
+ .addr(mem_addr[2:0]),
+ .d_i(mem_d_o),
+ .d_o(),
+ // registered data
+ .rx_d_m1(rx2_d_m1),
+ .rx_d_m2(rx2_d_m2),
+ .rx_d_m3(rx2_d_m3),
+ .rx_d_m4(rx2_d_m4),
+ // filter
+ .new_frame (rx_sop[2]),
+ .block(1'b0),
+ .invert(1'b1),
+ .trigger(rx_mac_keep[2]),
+ .keep(rx_pf_keep_21)
+ );
+
+ drop_fifo drop_fifo_21(
+ .rstn(sys_rstn),
+ .phy_up(phy_up[2]),
+ .rx_clk(phy2_rx_clk),
+ .tx_clk(pclk),
+ .enable(1'b1), // ipv4_rx_keep[1]
+ // control
+ .keep (rx_pf_keep_21),
+ .passthrough(1'b0),
+ // input
+ .we_in(rx_mac_fifo_we[2]),
+ .wr_done(rx_mac_wr_done[2]),
+ .rx_idle(rx_idle[2]),
+ .rx_error(rx_mac_error[2]),
+ .d_in(rx_mac_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(sys_rstn),
+ .clk (pclk),
+ // input
+ .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[2])
+ );
+
+`endif
+
+ dpram_inf #(.ADDR_WIDTH(10), .DPRAM_INIT("param_ram_2.txt")) param_ram_2(
+ .rstn(sys_rstn),
+ // Port A
+ .a_clk(cont_clk),
+ .a_clk_e(param_sel[2]),
+ .a_we(1'b0),
+ .a_oe(mem_oe),
+ .a_addr(mem_addr[9:0]),
+ .a_din(mem_d_o[8:0]),
+ .a_dout(param_ram_2_do),
+ // Port B
+ .b_clk(pclk),
+ .b_clk_e(param_phy2_ce),
+ .b_we(param_phy2_we),
+ .b_oe(1'b1),
+ .b_addr(param_phy2_addr[9:0]),
+ .b_din(param_phy2_dout),
+ .b_dout(param_phy2_din)
+ );
+
+ fcs fcs_rx_2(
+ .rstn(sys_rstn),
+ .clk(phy2_rx_clk),
+ .init(fcs_rx_init[2]),
+ .enable(fcs_rx_enable[2]),
+ .addr(fcs_rx_addr2),
+ .din(fcs_rx_din2),
+ .dout(fcs_rx_dout2)
+ );
+
+ fcs fcs_tx_2(
+ .rstn(sys_rstn),
+ .clk(pclk),
+ .init(fcs_tx_init[2]),
+ .enable(fcs_tx_enable[2]),
+ .addr(fcs_tx_addr2),
+ .din(fcs_tx_din2),
+ .dout(fcs_tx_dout2)
+ );
+
+
+`ifdef PASSTHROUGH
+ // phy0_tx_clk = phy1_rx_clk;
+ // Bits 3:0 on the positive edge of TX_CLK and bits 7:4 on the negative edge of TX_CLK.
+ // Note that PHY TX (output) clocks are routed through a DDR.
+ ddro rgmii_tx_0(
+ .aclr(1'b0),
+ .datain_h({1'b1, rx1_ctl_i_m4[0],rx1_d_i_m4[3:0]}),
+ .datain_l({1'b0, rx1_ctl_i_m4[1],rx1_d_i_m4[7:4]}),
+ .oe(1'b1),
+ .outclock(phy1_rx_clk),
+ .dataout({phy0_tx_clk, phy0_tx_ctl, phy0_tx_d}));
+
+ // phy1_tx_clk = phy0_rx_clk;
+ ddro rgmii_tx_1(
+ .aclr(1'b0),
+ .datain_h({1'b1, rx0_ctl_i_m4[0],rx0_d_i_m4[3:0]}),
+ .datain_l({1'b0, rx0_ctl_i_m4[1],rx0_d_i_m4[7:4]}),
+ .oe(1'b1),
+ .outclock(phy0_rx_clk),
+ .dataout({phy1_tx_clk, phy1_tx_ctl, phy1_tx_d}));
+
+ // phy2_tx_clk = phy0_rx_clk;
+ ddro rgmii_tx_2(
+ .aclr(1'b0),
+ .datain_h({1'b1, rx0_ctl_i_m4[0],rx0_d_i_m4[3:0]}),
+ .datain_l({1'b0, rx0_ctl_i_m4[1],rx0_d_i_m4[7:4]}),
+ .oe(1'b1),
+ .outclock(phy0_rx_clk),
+ .dataout({phy2_tx_clk, phy2_tx_ctl, phy2_tx_d}));
+
+`else
+
+ ddro rgmii_tx_0(
+ .aclr(1'b0),
+ .datain_h({1'b1, tx0_ctl[0], tx0_d[3:0]}),
+ .datain_l({1'b0, tx0_ctl[1], tx0_d[7:4]}),
+ .oe(1'b1),
+ .outclock(pclk),
+ .dataout({phy0_tx_clk, phy0_tx_ctl, phy0_tx_d}));
+
+ ddro rgmii_tx_1(
+ .aclr(1'b0),
+ .datain_h({1'b1, tx1_ctl[0],tx1_d[3:0]}),
+ .datain_l({1'b0, tx1_ctl[1],tx1_d[7:4]}),
+ .oe(1'b1),
+ .outclock(pclk),
+ .dataout({phy1_tx_clk, phy1_tx_ctl, phy1_tx_d}));
+
+ ddro rgmii_tx_2(
+ .aclr(1'b0),
+ .datain_h({1'b1, tx2_ctl[0],tx2_d[3:0]}),
+ .datain_l({1'b0, tx2_ctl[1],tx2_d[7:4]}),
+ .oe(1'b1),
+ .outclock(pclk),
+ .dataout({phy2_tx_clk, phy2_tx_ctl, phy2_tx_d}));
+
+`endif
+
+// Debug
+
+ //Heart beat cnt for LEDs and general debug
+ always @(posedge cont_clk, negedge sys_rstn)
+ if (!sys_rstn)
+ heart_beat_cnt <= 26'h0;
+ else
+ heart_beat_cnt <= heart_beat_cnt + 1'b1;
+
+ always @(posedge pclk, negedge sys_rstn)
+ if (!sys_rstn)
+ evt_toggle <= 1'b0;
+ else if (mle_evt_start)
+ evt_toggle <= ~evt_toggle;
+
+ assign fpga_led[0] = heart_beat_cnt[22];
+ assign fpga_led[1] = heart_beat_cnt[23];
+ assign fpga_led[2] = evt_toggle;
+
+endmodule

Highly Recommended Verilog Books