mirror of
https://github.com/fpganinja/taxi.git
synced 2026-05-17 21:10:55 -07:00
eth: Add 1000BASE-X PCS core to AC701 example design
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
17
src/eth/example/AC701/fpga/ip/basex_pcs_pma_0.tcl
Normal file
17
src/eth/example/AC701/fpga/ip/basex_pcs_pma_0.tcl
Normal file
@@ -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]
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
58
src/eth/example/AC701/fpga/syn/sfp.xdc
Normal file
58
src/eth/example/AC701/fpga/syn/sfp.xdc
Normal file
@@ -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}]
|
||||
@@ -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
|
||||
|
||||
@@ -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"),
|
||||
|
||||
Reference in New Issue
Block a user