diff --git a/src/eth/example/AC701/fpga/README.md b/src/eth/example/AC701/fpga/README.md index 53dcffc..2156baf 100644 --- a/src/eth/example/AC701/fpga/README.md +++ b/src/eth/example/AC701/fpga/README.md @@ -4,18 +4,21 @@ This example design targets the Xilinx AC701 FPGA board. -The design places a looped-back MACs the BASE-T port, as well as XFCP on the USB UART for monitoring and control. +The design places looped-back MACs on both the BASE-T port and the SFP+ cage, as well as XFCP on the USB UART for monitoring and control. * USB UART * XFCP (921600 baud) * RJ-45 Ethernet port with Marvell 88E1116 PHY * Looped-back MAC via RGMII +* SFP+ cage + * Looped-back 1000BASE-X via Xilinx PCS/PMA core and GTX transceiver ## Board details * FPGA: XC7A200T-2FBG676C * USB UART: Silicon Labs CP2103 * 1000BASE-T PHY: Marvell 88E1116 via RGMII +* 1000BASE-X PHY: Xilinx PCS/PMA core via GTX transceiver ## Licensing diff --git a/src/eth/example/AC701/fpga/fpga/Makefile b/src/eth/example/AC701/fpga/fpga/Makefile index c2a7eaa..b257573 100644 --- a/src/eth/example/AC701/fpga/fpga/Makefile +++ b/src/eth/example/AC701/fpga/fpga/Makefile @@ -18,6 +18,7 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src # Files for synthesis SYN_FILES = $(RTL_DIR)/fpga.sv SYN_FILES += $(RTL_DIR)/fpga_core.sv +SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_rgmii_fifo.f SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv @@ -32,6 +33,7 @@ XDC_FILES += ../syn/fpga.xdc XDC_FILES += ../syn/gpio.xdc XDC_FILES += ../syn/i2c.xdc XDC_FILES += ../syn/phy.xdc +XDC_FILES += ../syn/sfp.xdc XDC_FILES += ../syn/eth_rgmii.xdc XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_rgmii_phy_if.tcl XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl @@ -40,7 +42,7 @@ XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl # IP -#IP_TCL_FILES = ../ip/sgmii_pcs_pma_0.tcl +IP_TCL_FILES += ../ip/basex_pcs_pma_0.tcl # Configuration #CONFIG_TCL_FILES = ./config.tcl diff --git a/src/eth/example/AC701/fpga/ip/basex_pcs_pma_0.tcl b/src/eth/example/AC701/fpga/ip/basex_pcs_pma_0.tcl new file mode 100644 index 0000000..3382358 --- /dev/null +++ b/src/eth/example/AC701/fpga/ip/basex_pcs_pma_0.tcl @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2026 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +create_ip -name gig_ethernet_pcs_pma -vendor xilinx.com -library ip -module_name basex_pcs_pma_0 + +set_property -dict [list \ + CONFIG.Standard {1000BASEX} \ + CONFIG.Physical_Interface {Transceiver} \ + CONFIG.Management_Interface {false} \ + CONFIG.Auto_Negotiation {false} \ + CONFIG.SupportLevel {Include_Shared_Logic_in_Core} \ +] [get_ips basex_pcs_pma_0] diff --git a/src/eth/example/AC701/fpga/rtl/fpga.sv b/src/eth/example/AC701/fpga/rtl/fpga.sv index 0bfbc85..10cdcb0 100644 --- a/src/eth/example/AC701/fpga/rtl/fpga.sv +++ b/src/eth/example/AC701/fpga/rtl/fpga.sv @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT /* -Copyright (c) 2014-2026 FPGA Ninja, LLC +Copyright (c) 2014-2025 FPGA Ninja, LLC Authors: - Alex Forencich @@ -61,6 +61,20 @@ module fpga # inout wire logic i2c_sda, output wire logic i2c_mux_reset, + /* + * Ethernet: SFP+ + */ + input wire logic sfp_rx_p, + input wire logic sfp_rx_n, + output wire logic sfp_tx_p, + output wire logic sfp_tx_n, + input wire logic sfp_mgt_refclk_0_p, + input wire logic sfp_mgt_refclk_0_n, + output wire logic [1:0] sfp_mgt_clk_sel, + + output wire logic sfp_tx_disable, + input wire logic sfp_rx_los, + /* * Ethernet: 1000BASE-T RGMII */ @@ -259,6 +273,113 @@ assign i2c_scl = i2c_scl_o ? 1'bz : 1'b0; assign i2c_sda_i = i2c_sda; assign i2c_sda = i2c_sda_o ? 1'bz : 1'b0; +// 1000BASE-X SFP +assign sfp_mgt_clk_sel = 2'b00; + +wire sfp_gmii_clk_int; +wire sfp_gmii_rst_int; +wire sfp_gmii_clk_en_int; +wire [7:0] sfp_gmii_txd_int; +wire sfp_gmii_tx_en_int; +wire sfp_gmii_tx_er_int; +wire [7:0] sfp_gmii_rxd_int; +wire sfp_gmii_rx_dv_int; +wire sfp_gmii_rx_er_int; + +wire sfp_gtrefclk; +wire sfp_gtrefclk_bufg; +wire sfp_txuserclk; +wire sfp_txuserclk2; +wire sfp_rxuserclk; +wire sfp_rxuserclk2; +wire sfp_pma_reset; +wire sfp_mmcm_locked; + +wire sfp_resetdone; + +assign sfp_gmii_clk_int = sfp_txuserclk2; + +taxi_sync_reset #( + .N(4) +) +sync_reset_sfp_inst ( + .clk(sfp_gmii_clk_int), + .rst(rst_int || !sfp_resetdone), + .out(sfp_gmii_rst_int) +); + +wire [15:0] sfp_status_vect; + +wire sfp_status_link_status = sfp_status_vect[0]; +wire sfp_status_link_synchronization = sfp_status_vect[1]; +wire sfp_status_rudi_c = sfp_status_vect[2]; +wire sfp_status_rudi_i = sfp_status_vect[3]; +wire sfp_status_rudi_invalid = sfp_status_vect[4]; +wire sfp_status_rxdisperr = sfp_status_vect[5]; +wire sfp_status_rxnotintable = sfp_status_vect[6]; +wire sfp_status_phy_link_status = sfp_status_vect[7]; +wire [1:0] sfp_status_remote_fault_encdg = sfp_status_vect[9:8]; +wire [1:0] sfp_status_speed = sfp_status_vect[11:10]; +wire sfp_status_duplex = sfp_status_vect[12]; +wire sfp_status_remote_fault = sfp_status_vect[13]; +wire [1:0] sfp_status_pause = sfp_status_vect[15:14]; + +wire [4:0] sfp_config_vect; + +assign sfp_config_vect[4] = 1'b0; // autonegotiation enable +assign sfp_config_vect[3] = 1'b0; // isolate +assign sfp_config_vect[2] = 1'b0; // power down +assign sfp_config_vect[1] = 1'b0; // loopback enable +assign sfp_config_vect[0] = 1'b0; // unidirectional enable + +basex_pcs_pma_0 +sfp_pcspma ( + // Transceiver Interface + .gtrefclk_p(sfp_mgt_refclk_0_p), + .gtrefclk_n(sfp_mgt_refclk_0_n), + .gtrefclk_out(sfp_gtrefclk), + .gtrefclk_bufg_out(sfp_gtrefclk_bufg), + .txp(sfp_tx_p), + .txn(sfp_tx_n), + .rxp(sfp_rx_p), + .rxn(sfp_rx_n), + .resetdone(sfp_resetdone), + .userclk_out(sfp_txuserclk), + .userclk2_out(sfp_txuserclk2), + .rxuserclk_out(sfp_rxuserclk), + .rxuserclk2_out(sfp_rxuserclk2), + .independent_clock_bufg(clk_int), + .pma_reset_out(sfp_pma_reset), + .mmcm_locked_out(sfp_mmcm_locked), + .gt0_pll0outclk_out(), + .gt0_pll0outrefclk_out(), + .gt0_pll1outclk_out(), + .gt0_pll1outrefclk_out(), + .gt0_pll0lock_out(), + .gt0_pll0refclklost_out(), + // GMII Interface + .gmii_txd(sfp_gmii_txd_int), + .gmii_tx_en(sfp_gmii_tx_en_int), + .gmii_tx_er(sfp_gmii_tx_er_int), + .gmii_rxd(sfp_gmii_rxd_int), + .gmii_rx_dv(sfp_gmii_rx_dv_int), + .gmii_rx_er(sfp_gmii_rx_er_int), + .gmii_isolate(), + // Management: Alternative to MDIO Interface + .configuration_vector(sfp_config_vect), + .status_vector(sfp_status_vect), + // General IO's + .reset(rst_int), + .signal_detect(1'b1) +); + +assign sfp_gmii_clk_en_int = 1'b1; + +// SGMII interface debug: +// SW4:1 (sw[3]) off for payload byte, on for status vector +// SW4:4 (sw[0]) off for LSB of status vector, on for MSB +// assign led = sw[3] ? (sw[0] ? sfp_status_vect[15:8] : sfp_status_vect[7:0]) : led_int; + wire [3:0] phy_rxd_int; wire phy_rx_ctl_int; @@ -334,7 +455,7 @@ core_inst ( .btnr(btnr_int), .btnc(btnc_int), .sw(sw_int), - .led(led_int), + .led(led), /* * UART: 115200 bps, 8N1 @@ -352,6 +473,21 @@ core_inst ( .i2c_sda_i(i2c_sda_i), .i2c_sda_o(i2c_sda_o), + /* + * Ethernet: 1000BASE-X SFP + */ + .sfp_gmii_clk(sfp_gmii_clk_int), + .sfp_gmii_rst(sfp_gmii_rst_int), + .sfp_gmii_clk_en(sfp_gmii_clk_en_int), + .sfp_gmii_rxd(sfp_gmii_rxd_int), + .sfp_gmii_rx_dv(sfp_gmii_rx_dv_int), + .sfp_gmii_rx_er(sfp_gmii_rx_er_int), + .sfp_gmii_txd(sfp_gmii_txd_int), + .sfp_gmii_tx_en(sfp_gmii_tx_en_int), + .sfp_gmii_tx_er(sfp_gmii_tx_er_int), + .sfp_tx_disable(sfp_tx_disable), + .sfp_rx_los(sfp_rx_los), + /* * Ethernet: 1000BASE-T RGMII */ diff --git a/src/eth/example/AC701/fpga/rtl/fpga_core.sv b/src/eth/example/AC701/fpga/rtl/fpga_core.sv index 8662468..1998cda 100644 --- a/src/eth/example/AC701/fpga/rtl/fpga_core.sv +++ b/src/eth/example/AC701/fpga/rtl/fpga_core.sv @@ -22,7 +22,7 @@ module fpga_core # // vendor ("GENERIC", "XILINX", "ALTERA") parameter string VENDOR = "XILINX", // device family - parameter string FAMILY = "kintex7", + parameter string FAMILY = "artix7", // Use 90 degree clock for RGMII transmit parameter logic USE_CLK90 = 1'b1 ) @@ -62,6 +62,21 @@ module fpga_core # input wire logic i2c_sda_i, output wire logic i2c_sda_o, + /* + * Ethernet: 1000BASE-X SFP + */ + input wire logic sfp_gmii_clk, + input wire logic sfp_gmii_rst, + input wire logic sfp_gmii_clk_en, + input wire logic [7:0] sfp_gmii_rxd, + input wire logic sfp_gmii_rx_dv, + input wire logic sfp_gmii_rx_er, + output wire logic [7:0] sfp_gmii_txd, + output wire logic sfp_gmii_tx_en, + output wire logic sfp_gmii_tx_er, + output wire logic sfp_tx_disable, + input wire logic sfp_rx_los, + /* * Ethernet: 1000BASE-T */ @@ -157,7 +172,7 @@ xfcp_stats_inst ( .s_axis_stat(axis_stat) ); -taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(10)) axis_eth_stat[1](); +taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(10)) axis_eth_stat[2](); taxi_axis_arb_mux #( .S_COUNT($size(axis_eth_stat)), @@ -229,7 +244,7 @@ taxi_eth_mac_1g_rgmii_fifo #( .RX_FIFO_DEPTH(16384), .RX_FRAME_FIFO(1) ) -eth_mac_inst ( +baset_mac_inst ( .gtx_clk(clk), .gtx_clk90(clk90), .gtx_rst(rst), @@ -288,6 +303,94 @@ eth_mac_inst ( .cfg_rx_enable(1'b1) ); +// SFP+ +assign sfp_tx_disable = 1'b0; + +taxi_axis_if #(.DATA_W(8), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_sfp_eth(); +taxi_axis_if #(.DATA_W(96), .KEEP_W(1), .ID_W(8)) axis_sfp_tx_cpl(); + +taxi_eth_mac_1g_fifo #( + .PADDING_EN(1), + .MIN_FRAME_LEN(64), + .STAT_EN(1), + .STAT_TX_LEVEL(1), + .STAT_RX_LEVEL(1), + .STAT_ID_BASE(16+16), + .STAT_UPDATE_PERIOD(1024), + .STAT_STR_EN(1), + .STAT_PREFIX_STR("SFP"), + .TX_FIFO_DEPTH(16384), + .TX_FRAME_FIFO(1), + .RX_FIFO_DEPTH(16384), + .RX_FRAME_FIFO(1) +) +sfp_mac_inst ( + .rx_clk(sfp_gmii_clk), + .rx_rst(sfp_gmii_rst), + .tx_clk(sfp_gmii_clk), + .tx_rst(sfp_gmii_rst), + .logic_clk(clk), + .logic_rst(rst), + + /* + * Transmit interface (AXI stream) + */ + .s_axis_tx(axis_sfp_eth), + .m_axis_tx_cpl(axis_sfp_tx_cpl), + + /* + * Receive interface (AXI stream) + */ + .m_axis_rx(axis_sfp_eth), + + /* + * GMII interface + */ + .gmii_rxd(sfp_gmii_rxd), + .gmii_rx_dv(sfp_gmii_rx_dv), + .gmii_rx_er(sfp_gmii_rx_er), + .gmii_txd(sfp_gmii_txd), + .gmii_tx_en(sfp_gmii_tx_en), + .gmii_tx_er(sfp_gmii_tx_er), + + /* + * Control + */ + .rx_clk_enable(sfp_gmii_clk_en), + .tx_clk_enable(sfp_gmii_clk_en), + .rx_mii_select(1'b0), + .tx_mii_select(1'b0), + + /* + * Statistics + */ + .stat_clk(clk), + .stat_rst(rst), + .m_axis_stat(axis_eth_stat[1]), + + /* + * Status + */ + .tx_error_underflow(), + .tx_fifo_overflow(), + .tx_fifo_bad_frame(), + .tx_fifo_good_frame(), + .rx_error_bad_frame(), + .rx_error_bad_fcs(), + .rx_fifo_overflow(), + .rx_fifo_bad_frame(), + .rx_fifo_good_frame(), + + /* + * Configuration + */ + .cfg_tx_max_pkt_len(16'd9218), + .cfg_tx_ifg(8'd12), + .cfg_tx_enable(1'b1), + .cfg_rx_max_pkt_len(16'd9218), + .cfg_rx_enable(1'b1) +); + endmodule `resetall diff --git a/src/eth/example/AC701/fpga/syn/sfp.xdc b/src/eth/example/AC701/fpga/syn/sfp.xdc new file mode 100644 index 0000000..cee8123 --- /dev/null +++ b/src/eth/example/AC701/fpga/syn/sfp.xdc @@ -0,0 +1,58 @@ +# SPDX-License-Identifier: MIT +# +# Copyright (c) 2014-2026 FPGA Ninja, LLC +# +# Authors: +# - Alex Forencich +# + +# XDC constraints for the Xilinx AC701 board +# part: xc7a200tfbg676-2 + +# GTX for Ethernet +set_property -dict {LOC AC12} [get_ports sfp_rx_p] ;# MGTXRXP0_213 GTPE2_CHANNEL_X0Y0 / GTPE2_COMMON_X0Y0 from P3.13 +set_property -dict {LOC AD12} [get_ports sfp_rx_n] ;# MGTXRXN0_213 GTPE2_CHANNEL_X0Y0 / GTPE2_COMMON_X0Y0 from P3.12 +set_property -dict {LOC AC10} [get_ports sfp_tx_p] ;# MGTXTXP0_213 GTPE2_CHANNEL_X0Y0 / GTPE2_COMMON_X0Y0 from P3.18 +set_property -dict {LOC AD10} [get_ports sfp_tx_n] ;# MGTXTXN0_213 GTPE2_CHANNEL_X0Y0 / GTPE2_COMMON_X0Y0 from P3.19 +set_property -dict {LOC AA13} [get_ports sfp_mgt_refclk_0_p] ;# MGTREFCLK0P_213 from U3.10 +set_property -dict {LOC AB13} [get_ports sfp_mgt_refclk_0_n] ;# MGTREFCLK0N_213 from U3.11 +#set_property -dict {LOC AA11} [get_ports sfp_mgt_refclk_1_p] ;# MGTREFCLK1P_213 from U4.10 +#set_property -dict {LOC AB11} [get_ports sfp_mgt_refclk_1_n] ;# MGTREFCLK1N_213 from U4.11 +#set_property -dict {LOC D23 IOSTANDARD LVDS_25} [get_ports sfp_recclk_p] ;# to Si5324 U24.16 CKIN1_P +#set_property -dict {LOC D24 IOSTANDARD LVDS_25} [get_ports sfp_recclk_n] ;# to Si5324 U24.17 CKIN1_N + +#set_property -dict {LOC B24 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports si5324_rst] +#set_property -dict {LOC M19 IOSTANDARD LVCMOS25 PULLUP true} [get_ports si5324_int] + +set_property -dict {LOC R18 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {sfp_tx_disable}] +set_property -dict {LOC R23 IOSTANDARD LVCMOS33} [get_ports {sfp_rx_los}] + +# U3 clock mux for SFP_MGT_CLK_0 +# 2'b00 = EPHYCLK_Q0 (125 MHz) +# 2'b01 = SI5324_OUT0 +# 2'b10 = FMC1_HPC_GBTCLK0 +# 2'b00 = NC +set_property -dict {LOC B26 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports "sfp_mgt_clk_sel[0]"] +set_property -dict {LOC C24 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports "sfp_mgt_clk_sel[1]"] + +# 125 MHz MGT reference clock (SGMII, 1000BASE-X) +create_clock -period 8.000 -name sfp_mgt_refclk_0 [get_ports sfp_mgt_refclk_0_p] + +# U4 clock mux for SFP_MGT_CLK_1 +# 2'b00 = SMA_MGT_REFCLK +# 2'b01 = SI5324_OUT1 +# 2'b10 = FMC1_HPC_GBTCLK1 +# 2'b00 = NC +#set_property -dict {LOC A24 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports "pcie_mgt_clk_sel[0]"] +#set_property -dict {LOC C26 IOSTANDARD LVCMOS25 SLEW SLOW DRIVE 12} [get_ports "pcie_mgt_clk_sel[1]"] + +# 125 MHz MGT reference clock (SGMII, 1000BASE-X) +#create_clock -period 6.400 -name sgmii_mgt_refclk_1 [get_ports sfp_mgt_refclk_1_p] + +#set_false_path -to [get_ports {si5324_rst}] +#set_output_delay 0 [get_ports {si5324_rst}] +#set_false_path -from [get_ports {si5324_int}] +#set_input_delay 0 [get_ports {si5324_int}] + +set_false_path -to [get_ports {sfp_tx_disable}] +set_output_delay 0 [get_ports {sfp_tx_disable}] diff --git a/src/eth/example/AC701/fpga/tb/fpga_core/Makefile b/src/eth/example/AC701/fpga/tb/fpga_core/Makefile index 9f29be3..6caeeee 100644 --- a/src/eth/example/AC701/fpga/tb/fpga_core/Makefile +++ b/src/eth/example/AC701/fpga/tb/fpga_core/Makefile @@ -23,6 +23,7 @@ COCOTB_TOPLEVEL = $(DUT) MODULE = $(COCOTB_TEST_MODULES) TOPLEVEL = $(COCOTB_TOPLEVEL) VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv +VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_fifo.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/taxi_eth_mac_1g_rgmii_fifo.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv diff --git a/src/eth/example/AC701/fpga/tb/fpga_core/test_fpga_core.py b/src/eth/example/AC701/fpga/tb/fpga_core/test_fpga_core.py index 8664a8d..ff90e57 100644 --- a/src/eth/example/AC701/fpga/tb/fpga_core/test_fpga_core.py +++ b/src/eth/example/AC701/fpga/tb/fpga_core/test_fpga_core.py @@ -12,7 +12,6 @@ Authors: import logging import os -import pytest import cocotb_test.simulator import cocotb @@ -30,14 +29,21 @@ class TB: self.log = logging.getLogger("cocotb.tb") self.log.setLevel(logging.DEBUG) - # cocotb.start_soon(Clock(dut.phy_sgmii_clk, 8, units="ns").start()) - self.baset_phy = RgmiiPhy(dut.phy_txd, dut.phy_tx_ctl, dut.phy_tx_clk, dut.phy_rxd, dut.phy_rx_ctl, dut.phy_rx_clk, speed=speed) + cocotb.start_soon(Clock(dut.sfp_gmii_clk, 8, units="ns").start()) + + self.sfp_source = GmiiSource(dut.sfp_gmii_rxd, dut.sfp_gmii_rx_er, dut.sfp_gmii_rx_dv, + dut.sfp_gmii_clk, dut.sfp_gmii_rst, dut.sfp_gmii_clk_en) + self.sfp_sink = GmiiSink(dut.sfp_gmii_txd, dut.sfp_gmii_tx_er, dut.sfp_gmii_tx_en, + dut.sfp_gmii_clk, dut.sfp_gmii_rst, dut.sfp_gmii_clk_en) + self.uart_source = UartSource(dut.uart_rxd, baud=921600, bits=8, stop_bits=1) self.uart_sink = UartSink(dut.uart_txd, baud=921600, bits=8, stop_bits=1) + dut.sfp_gmii_clk_en.setimmediatevalue(1) + dut.btnu.setimmediatevalue(0) dut.btnl.setimmediatevalue(0) dut.btnd.setimmediatevalue(0) @@ -51,16 +57,19 @@ class TB: async def init(self): self.dut.rst.setimmediatevalue(0) + self.dut.sfp_gmii_rst.setimmediatevalue(0) for k in range(10): await RisingEdge(self.dut.clk) self.dut.rst.value = 1 + self.dut.sfp_gmii_rst.value = 1 for k in range(10): await RisingEdge(self.dut.clk) self.dut.rst.value = 0 + self.dut.sfp_gmii_rst.value = 0 async def _run_clk(self): t = Timer(2, 'ns') @@ -130,6 +139,10 @@ async def run_test(dut): tests.append(cocotb.start_soon(mac_test(tb, tb.baset_phy.rx, tb.baset_phy.tx))) + tb.log.info("Start SFP MAC loopback test") + + tests.append(cocotb.start_soon(mac_test(tb, tb.sfp_source, tb.sfp_sink))) + await Combine(*tests) await RisingEdge(dut.clk) @@ -164,6 +177,7 @@ def test_fpga_core(request): verilog_sources = [ os.path.join(rtl_dir, f"{dut}.sv"), + os.path.join(taxi_src_dir, "eth", "rtl", "taxi_eth_mac_1g_fifo.f"), os.path.join(taxi_src_dir, "eth", "rtl", "taxi_eth_mac_1g_rgmii_fifo.f"), os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_if_uart.f"), os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_switch.sv"),