fpga: x4xx: Replace Ethernet transport adapter

Original-commit: 34cee97e6206151e80d33e0e5367dcac62038a67
This commit is contained in:
Wade Fife
2024-06-11 10:20:07 +02:00
committed by Joerg Hofrichter
parent 8669c68048
commit 872de917bf
15 changed files with 880 additions and 789 deletions
-3
View File
@@ -56,9 +56,6 @@ endif
##################################################
TOP_SRCS = \
x4xx.v \
x4xx_qsfp_wrapper_temp.sv \
x4xx_qsfp_wrapper.sv \
x4xx_mgt_io_core.sv \
x4xx_core.v \
x4xx_core_common.v \
x4xx_global_regs.v \
@@ -1,19 +0,0 @@
#
# Copyright 2021 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# Description:
# 10 GbE Timing Constraints.
#
# Specify which clock is used for dclk in the 10 GbE IP.
set DCLK_NAME clk100
# Constraints taken from xge_pcs_pma_exceptions.xdc in the example design.
set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -datapath_only 6.40
set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -datapath_only 6.40
set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -to [get_clocks $DCLK_NAME] -datapath_only 6.40
set_max_delay -from [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -to [get_clocks $DCLK_NAME] -datapath_only 6.40
set_max_delay -from [get_clocks $DCLK_NAME] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/TXOUTCLK}]] -datapath_only 10.000
set_max_delay -from [get_clocks $DCLK_NAME] -to [get_clocks -of_objects [get_pins -hierarchical -filter {NAME =~ */channel_inst/*_CHANNEL_PRIM_INST/RXOUTCLK}]] -datapath_only 10.000
-150
View File
@@ -1,150 +0,0 @@
#
# Copyright 2021 Ettus Research, a National Instruments Brand
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
#-------------------------------------------------
# Top-of-Makefile
#-------------------------------------------------
# Define BASE_DIR to point to the "top" dir
BASE_DIR = $(abspath ../../../../top)
# Include viv_sim_preamble after defining BASE_DIR
include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
#-------------------------------------------------
# Design Specific
#-------------------------------------------------
# Define part using PART_ID (<device>/<package>/<speedgrade>)
ARCH = zynquplusRFSOC
PART_ID = xczu28dr/ffvg1517/-1/e
# Include makefiles and sources for the DUT and its dependencies
include $(BASE_DIR)/../lib/axi4_sv/Makefile.srcs
include $(BASE_DIR)/../lib/axi4s_sv/Makefile.srcs
include $(BASE_DIR)/../lib/xge/Makefile.srcs
include $(BASE_DIR)/../lib/xge_interface/Makefile.srcs
include $(BASE_DIR)/../lib/rfnoc/utils/Makefile.srcs
include $(BASE_DIR)/../lib/rfnoc/xport_sv/Makefile.srcs
include $(BASE_DIR)/../lib/rfnoc/crossbar/Makefile.srcs
include $(BASE_DIR)/../lib/rfnoc/core/Makefile.srcs
DESIGN_SRCS += $(abspath \
$(AXI4_SV_SRCS) \
$(AXI4S_SV_SRCS) \
$(XGE_SRCS) \
$(XGE_INTERFACE_SRCS) \
$(RFNOC_UTIL_SRCS) \
$(RFNOC_XPORT_SV_SRCS) \
$(RFNOC_XBAR_SRCS) \
$(RFNOC_CORE_SRCS) \
)
# Add files for the DUT
DESIGN_SRCS += $(abspath \
$(BASE_DIR)/x400/x4xx_mgt_io_core.sv \
$(BASE_DIR)/x400/x4xx_qsfp_wrapper.sv \
$(BASE_DIR)/x400/x4xx_qsfp_wrapper_temp.sv \
)
#-------------------------------------------------
# IP Specific
#-------------------------------------------------
# If simulation contains IP, define the IP_DIR and point
# it to the base level IP directory
IP_DIR = ../../ip
# Include makefiles and sources for all IP components
# *after* defining the IP_DIR
include $(IP_DIR)/axi_interconnect_eth_bd/Makefile.inc
include $(IP_DIR)/axi_interconnect_dma_bd/Makefile.inc
include $(IP_DIR)/axi_eth_dma_bd/Makefile.inc
include $(IP_DIR)/xge_pcs_pma/Makefile.inc
include $(IP_DIR)/eth_100g_bd/Makefile.inc
DESIGN_SRCS += $(abspath \
$(IP_AXI_INTERCONNECT_ETH_HDL_SRCS) \
$(IP_AXI_INTERCONNECT_ETH_BD_SRCS) \
$(IP_AXI_INTERCONNECT_DMA_HDL_SRCS) \
$(IP_AXI_INTERCONNECT_DMA_BD_SRCS) \
$(IP_AXI_ETH_DMA_BD_HDL_SRCS) \
$(IP_AXI_ETH_DMA_BD_SRCS) \
$(XGE_PCS_PMA_SRCS) \
$(IP_100G_HDL_SRCS) \
$(IP_100G_BD_SRCS) \
)
#-------------------------------------------------
# ModelSim Specific
#-------------------------------------------------
# Note: ipshared/*/hdl/sc_util_*_rfs.sv needs to be compiled before the rest of
# the ipshared files.
IP_AXI_ETH_DMA_BD_HDL_SIM_SRCS = $(wildcard $(addprefix $(IP_BUILD_DIR)/axi_eth_dma_bd/axi_eth_dma_bd/, \
sim/axi_eth_dma_bd.v \
ip/*/sim/*.h \
ip/*/sim/*.v \
ip/*/sim/*.vhd \
ip/*/bd_0/hdl/*.v \
ip/*/bd_0/sim/*.v \
ip/*/bd_0/ip/ip_*/sim/*.v \
ip/*/bd_0/ip/ip_*/sim/*.sv \
ip/*/bd_0/ip/ip_*/sim/*.vhd \
ipshared/*/hdl/sc_util_*_rfs.sv \
ipshared/*/hdl/*.sv \
ipshared/*/hdl/*.v \
ipshared/*/simulation/*.v \
ipshared/*/hdl/verilog/*.v \
ipshared/*/hdl/verilog/*.svh \
ipshared/*/hdl/verilog/*.vh \
))
IP_AXI_INTERCONNECT_DMA_BD_HDL_SIM_SRCS = $(wildcard $(addprefix $(IP_BUILD_DIR)/axi_interconnect_dma_bd/axi_interconnect_dma_bd/, \
sim/*.v \
ip/*/sim/*.v \
))
MISC_IP_SIM_SRCS += \
$(VIVADO_PATH)/data/verilog/src/glbl.v \
$(abspath $(IP_BUILD_DIR)/xge_pcs_pma/model_10gbe.sv) \
DESIGN_SRCS += $(abspath \
$(IP_AXI_ETH_DMA_BD_HDL_SIM_SRCS) \
$(IP_AXI_INTERCONNECT_DMA_BD_HDL_SIM_SRCS) \
$(IP_AXI_INTERCONNECT_ETH_HDL_SIM_SRCS) \
$(IP_100G_HDL_SIM_SRCS) \
$(IP_XGE_PCS_PMA_HDL_SIM_SRCS) \
$(MISC_IP_SIM_SRCS) \
)
# Xilinx IP wants lots of libraries
MODELSIM_LIBS += secureip unimacro_ver unisims_ver xilinx_vip xpm
MODELSIM_ARGS += glbl -t 1fs
# Needed for the HACK_SRC, speeds up the alignment phase (still long!)
VLOG_ARGS += +define+SIM_SPEED_UP
# Suppressing the following worthless reminder.
#* Warning: M:/usrp4-hw/oss-repo/fpga/usrp3/lib/axi4s_sv/axi4s_remove_bytes.sv(228): (vlog-2583) [SVCHK] -
# Extra checking for conflicts with always_comb and always_latch variables is done at vopt time
SVLOG_ARGS += -suppress 2583
#-------------------------------------------------
# Testbench Specific
#-------------------------------------------------
# Define only one top-level module
TB_TOP_MODULE ?= x4xx_qsfp_wrapper_all_tb
SIM_TOP = $(TB_TOP_MODULE)
SIM_SRCS = \
$(abspath x4xx_qsfp_wrapper_tb.sv) \
$(abspath $(TB_TOP_MODULE).sv) \
#-------------------------------------------------
# Bottom-of-Makefile
#-------------------------------------------------
# Include all simulator specific makefiles here
# Each should define a unique target to simulate
# e.g. xsim, vsim, etc and a common "clean" target
include $(BASE_DIR)/../tools/make/viv_simulator.mak
@@ -1,85 +0,0 @@
//
// Copyright 2021 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_qsfp_wrapper_all_tb
//
// Description:
//
// Testbench for the QSFP wrapper to allow testing all protocols.
//
`include "./x4xx_mgt_types.vh"
module x4xx_qsfp_wrapper_all_tb;
x4xx_qsfp_wrapper_tb #(
.TEST_NAME ("100GbE_F"),
.PROTOCOL0 (`MGT_100GbE),
.CHDR_W (512),
.USE_MAC (0)
) ETH_100Gb_fast ();
x4xx_qsfp_wrapper_tb #(
.TEST_NAME ("10GbE_F"),
.PROTOCOL0 (`MGT_10GbE),
.CHDR_W (64),
.USE_MAC (0)
) ETH_10Gb_fast ();
x4xx_qsfp_wrapper_tb #(
.TEST_NAME ("10GbE_F_512"),
.PROTOCOL0 (`MGT_10GbE),
.CHDR_W (512),
.USE_MAC (0)
) ETH_10Gb_fast_512 ();
x4xx_qsfp_wrapper_tb #(
.TEST_NAME ("10GbE_x4_F"),
.PROTOCOL0 (`MGT_10GbE),
.PROTOCOL1 (`MGT_10GbE),
.PROTOCOL2 (`MGT_10GbE),
.PROTOCOL3 (`MGT_10GbE),
.CHDR_W (64),
.USE_MAC (0)
) ETH_10Gb_x4_fast ();
x4xx_qsfp_wrapper_tb #(
.TEST_NAME ("100GbE_512S"),
.PROTOCOL0 (`MGT_100GbE),
.CHDR_W (512),
.USE_MAC (1)
) ETH_100Gb_512serial ();
x4xx_qsfp_wrapper_tb #(
.TEST_NAME ("100GbE_128S"),
.PROTOCOL0 (`MGT_100GbE),
.CHDR_W (128),
.USE_MAC (1)
) ETH_100Gb_128serial ();
x4xx_qsfp_wrapper_tb #(
.TEST_NAME ("10GbE_S"),
.PROTOCOL0 (`MGT_10GbE),
.CHDR_W (64),
.USE_MAC (1)
) ETH_10Gb_serial ();
bit clk,rst;
sim_clock_gen #(100.0) clk_gen (clk, rst);
// Wait for all done
always_ff@(posedge clk) begin
if (ETH_100Gb_fast.test.done &&
ETH_10Gb_fast.test.done &&
ETH_10Gb_fast_512.test.done &&
ETH_10Gb_x4_fast.test.done &&
ETH_100Gb_512serial.test.done &&
ETH_100Gb_128serial.test.done &&
ETH_10Gb_serial.test.done
) $finish(1);
end
endmodule
File diff suppressed because it is too large Load Diff
+151 -280
View File
@@ -272,7 +272,6 @@ module x4xx (
`include "regmap/global_regs_regmap_utils.vh"
`include "regmap/versioning_utils.vh"
`include "x4xx_mgt_types.vh"
//---------------------------------------------------------------------------
@@ -323,19 +322,7 @@ module x4xx (
localparam NUM_TIMEKEEPERS = 1;
`endif
// Set the width for each transport adapter. All ports within a single QSFP
// will have the same width.
localparam [31:0] QSFP0_W = `CHDR_WIDTH;
localparam [31:0] QSFP1_W = `CHDR_WIDTH;
// Width of the signals used to connect the Ethernet transport adapters to
// RFNoC. Set this to the width of the widest port.
localparam [31:0] ENET_W = (QSFP0_W > QSFP1_W) ? QSFP0_W : QSFP1_W;
// Actual width of each SFP port's transport adapter interface. Each port of
// the same QSFP must have the same width.
localparam [8*32-1:0] ENET_WIDTHS = {{4{QSFP1_W}}, {4{QSFP0_W}}};
localparam RFNOC_PROTOVER = `RFNOC_PROTOVER;
localparam NET_CHDR_W = ENET_W;
localparam CHDR_W = `CHDR_WIDTH;
localparam DMA_W = `CHDR_WIDTH;
@@ -2452,19 +2439,6 @@ module x4xx (
wire [15:0] device_id;
wire rx_rec_clk_out1; // output GTY on QSFP1
// e2v and v2e are flattened arrays, where e2v_tdata[ENET_W*N +: ENET_W] is
// the data for RFNoC port N. RFNoC ports 0-3 map to QSFP0 and ports 4-7 map
// to QSFP1. Note that each port might use less than ENET_W bits.
wire [ENET_W*8-1:0] e2v_tdata;
wire [ 8-1:0] e2v_tlast;
wire [ 8-1:0] e2v_tready;
wire [ 8-1:0] e2v_tvalid;
wire [ENET_W*8-1:0] v2e_tdata;
wire [ 8-1:0] v2e_tlast;
wire [ 8-1:0] v2e_tready;
wire [ 8-1:0] v2e_tvalid;
`ifdef QSFP0_0
assign QSFP0_0_TX_P = qsfp0_tx_p[0];
assign QSFP0_0_TX_N = qsfp0_tx_n[0];
@@ -2539,239 +2513,6 @@ module x4xx (
assign qsfp1_rx_n[3] = 1'b1;
`endif
`ifdef QSFP0_0
x4xx_qsfp_wrapper_temp #(
`ifdef QSFP0_0
.PROTOCOL0 (`QSFP0_0),
`endif
`ifdef QSFP0_1
.PROTOCOL1 (`QSFP0_1),
`endif
`ifdef QSFP0_2
.PROTOCOL2 (`QSFP0_2),
`endif
`ifdef QSFP0_3
.PROTOCOL3 (`QSFP0_3),
`endif
.CHDR_W (QSFP0_W),
.NET_CHDR_W (NET_CHDR_W),
.BYTE_MTU (BYTE_MTU),
.PORTNUM (0),
.NODE_INST (0),
.RFNOC_PROTOVER (RFNOC_PROTOVER)
) x4xx_qsfp_wrapper_0 (
.areset (areset),
.refclk_p (MGT_REFCLK_LMK0_P),
.refclk_n (MGT_REFCLK_LMK0_N),
.clk100 (clk100), // IP configured for 100 MHz DClk
.bus_rst (bus_clk_rst),
.bus_clk (bus_clk),
.clk40_rst (clk40_rst),
.clk40 (clk40),
// Register Access
.s_axi_awaddr (axi_qsfp0_awaddr),
.s_axi_awvalid (axi_qsfp0_awvalid),
.s_axi_awready (axi_qsfp0_awready),
.s_axi_wdata (axi_qsfp0_wdata),
.s_axi_wstrb (axi_qsfp0_wstrb),
.s_axi_wvalid (axi_qsfp0_wvalid),
.s_axi_wready (axi_qsfp0_wready),
.s_axi_bresp (axi_qsfp0_bresp),
.s_axi_bvalid (axi_qsfp0_bvalid),
.s_axi_bready (axi_qsfp0_bready),
.s_axi_araddr (axi_qsfp0_araddr),
.s_axi_arvalid (axi_qsfp0_arvalid),
.s_axi_arready (axi_qsfp0_arready),
.s_axi_rdata (axi_qsfp0_rdata),
.s_axi_rresp (axi_qsfp0_rresp),
.s_axi_rvalid (axi_qsfp0_rvalid),
.s_axi_rready (axi_qsfp0_rready),
// DMA Access
.axi_hp_araddr (axi_hp0_araddr),
.axi_hp_arburst (axi_hp0_arburst),
.axi_hp_arcache (axi_hp0_arcache),
.axi_hp_arlen (axi_hp0_arlen),
.axi_hp_arlock (axi_hp0_arlock),
.axi_hp_arprot (axi_hp0_arprot),
.axi_hp_arqos (axi_hp0_arqos),
.axi_hp_arready (axi_hp0_arready),
.axi_hp_arsize (axi_hp0_arsize),
.axi_hp_arvalid (axi_hp0_arvalid),
.axi_hp_awaddr (axi_hp0_awaddr),
.axi_hp_awburst (axi_hp0_awburst),
.axi_hp_awcache (axi_hp0_awcache),
.axi_hp_awlen (axi_hp0_awlen),
.axi_hp_awlock (axi_hp0_awlock),
.axi_hp_awprot (axi_hp0_awprot),
.axi_hp_awqos (axi_hp0_awqos),
.axi_hp_awready (axi_hp0_awready),
.axi_hp_awsize (axi_hp0_awsize),
.axi_hp_awvalid (axi_hp0_awvalid),
.axi_hp_bready (axi_hp0_bready),
.axi_hp_bresp (axi_hp0_bresp),
.axi_hp_bvalid (axi_hp0_bvalid),
.axi_hp_rdata (axi_hp0_rdata),
.axi_hp_rlast (axi_hp0_rlast),
.axi_hp_rready (axi_hp0_rready),
.axi_hp_rresp (axi_hp0_rresp),
.axi_hp_rvalid (axi_hp0_rvalid),
.axi_hp_wdata (axi_hp0_wdata),
.axi_hp_wlast (axi_hp0_wlast),
.axi_hp_wready (axi_hp0_wready),
.axi_hp_wstrb (axi_hp0_wstrb),
.axi_hp_wvalid (axi_hp0_wvalid),
// Transceivers
.tx_p (qsfp0_tx_p),
.tx_n (qsfp0_tx_n),
.rx_p (qsfp0_rx_p),
.rx_n (qsfp0_rx_n),
// Ethernet to CHDR
.e2v_tdata ({ e2v_tdata [3*ENET_W +: QSFP0_W],
e2v_tdata [2*ENET_W +: QSFP0_W],
e2v_tdata [1*ENET_W +: QSFP0_W],
e2v_tdata [0*ENET_W +: QSFP0_W] }),
.e2v_tlast (e2v_tlast [0 +: 4]),
.e2v_tvalid (e2v_tvalid[0 +: 4]),
.e2v_tready (e2v_tready[0 +: 4]),
// CHDR to Ethernet
.v2e_tdata ({ v2e_tdata[3*ENET_W +: QSFP0_W],
v2e_tdata[2*ENET_W +: QSFP0_W],
v2e_tdata[1*ENET_W +: QSFP0_W],
v2e_tdata[0*ENET_W +: QSFP0_W] }),
.v2e_tlast (v2e_tlast [0 +: 4]),
.v2e_tvalid (v2e_tvalid[0 +: 4]),
.v2e_tready (v2e_tready[0 +: 4]),
// Misc
.eth_rx_irq (eth0_rx_irq),
.eth_tx_irq (eth0_tx_irq),
.device_id (device_id),
.rx_rec_clk_out (),
.port_info_0 (qsfp_port_0_0_info),
.port_info_1 (qsfp_port_0_1_info),
.port_info_2 (qsfp_port_0_2_info),
.port_info_3 (qsfp_port_0_3_info),
.link_up (eth0_link_up),
.activity (eth0_activity)
);
`endif
`ifdef QSFP1_0
x4xx_qsfp_wrapper_temp #(
`ifdef QSFP1_0
.PROTOCOL0 (`QSFP1_0),
`endif
`ifdef QSFP1_1
.PROTOCOL1 (`QSFP1_1),
`endif
`ifdef QSFP1_2
.PROTOCOL2 (`QSFP1_2),
`endif
`ifdef QSFP1_3
.PROTOCOL3 (`QSFP1_3),
`endif
.CHDR_W (QSFP1_W),
.NET_CHDR_W (NET_CHDR_W),
.BYTE_MTU (BYTE_MTU),
.PORTNUM (1),
.NODE_INST (4),
.RFNOC_PROTOVER (RFNOC_PROTOVER)
) x4xx_qsfp_wrapper_1 (
.areset (areset),
.refclk_p (MGT_REFCLK_LMK3_P),
.refclk_n (MGT_REFCLK_LMK3_N),
.clk100 (clk100), // IP configured for 100 MHz DClk
.bus_rst (bus_clk_rst),
.bus_clk (bus_clk),
.clk40_rst (clk40_rst),
.clk40 (clk40),
//Register Access
.s_axi_awaddr (axi_qsfp1_awaddr),
.s_axi_awvalid (axi_qsfp1_awvalid),
.s_axi_awready (axi_qsfp1_awready),
.s_axi_wdata (axi_qsfp1_wdata),
.s_axi_wstrb (axi_qsfp1_wstrb),
.s_axi_wvalid (axi_qsfp1_wvalid),
.s_axi_wready (axi_qsfp1_wready),
.s_axi_bresp (axi_qsfp1_bresp),
.s_axi_bvalid (axi_qsfp1_bvalid),
.s_axi_bready (axi_qsfp1_bready),
.s_axi_araddr (axi_qsfp1_araddr),
.s_axi_arvalid (axi_qsfp1_arvalid),
.s_axi_arready (axi_qsfp1_arready),
.s_axi_rdata (axi_qsfp1_rdata),
.s_axi_rresp (axi_qsfp1_rresp),
.s_axi_rvalid (axi_qsfp1_rvalid),
.s_axi_rready (axi_qsfp1_rready),
// DMA Access
.axi_hp_araddr (axi_hp1_araddr),
.axi_hp_arburst (axi_hp1_arburst),
.axi_hp_arcache (axi_hp1_arcache),
.axi_hp_arlen (axi_hp1_arlen),
.axi_hp_arlock (axi_hp1_arlock),
.axi_hp_arprot (axi_hp1_arprot),
.axi_hp_arqos (axi_hp1_arqos),
.axi_hp_arready (axi_hp1_arready),
.axi_hp_arsize (axi_hp1_arsize),
.axi_hp_arvalid (axi_hp1_arvalid),
.axi_hp_awaddr (axi_hp1_awaddr),
.axi_hp_awburst (axi_hp1_awburst),
.axi_hp_awcache (axi_hp1_awcache),
.axi_hp_awlen (axi_hp1_awlen),
.axi_hp_awlock (axi_hp1_awlock),
.axi_hp_awprot (axi_hp1_awprot),
.axi_hp_awqos (axi_hp1_awqos),
.axi_hp_awready (axi_hp1_awready),
.axi_hp_awsize (axi_hp1_awsize),
.axi_hp_awvalid (axi_hp1_awvalid),
.axi_hp_bready (axi_hp1_bready),
.axi_hp_bresp (axi_hp1_bresp),
.axi_hp_bvalid (axi_hp1_bvalid),
.axi_hp_rdata (axi_hp1_rdata),
.axi_hp_rlast (axi_hp1_rlast),
.axi_hp_rready (axi_hp1_rready),
.axi_hp_rresp (axi_hp1_rresp),
.axi_hp_rvalid (axi_hp1_rvalid),
.axi_hp_wdata (axi_hp1_wdata),
.axi_hp_wlast (axi_hp1_wlast),
.axi_hp_wready (axi_hp1_wready),
.axi_hp_wstrb (axi_hp1_wstrb),
.axi_hp_wvalid (axi_hp1_wvalid),
// Transceivers
.tx_p (qsfp1_tx_p),
.tx_n (qsfp1_tx_n),
.rx_p (qsfp1_rx_p),
.rx_n (qsfp1_rx_n),
// Ethernet to CHDR
.e2v_tdata ({ e2v_tdata[4*ENET_W + 3*ENET_W +: QSFP1_W],
e2v_tdata[4*ENET_W + 2*ENET_W +: QSFP1_W],
e2v_tdata[4*ENET_W + 1*ENET_W +: QSFP1_W],
e2v_tdata[4*ENET_W + 0*ENET_W +: QSFP1_W] }),
.e2v_tlast (e2v_tlast [4 +: 4]),
.e2v_tvalid (e2v_tvalid[4 +: 4]),
.e2v_tready (e2v_tready[4 +: 4]),
// CHDR to Ethernet
.v2e_tdata ({ v2e_tdata[4*ENET_W + 3*ENET_W +: QSFP1_W],
v2e_tdata[4*ENET_W + 2*ENET_W +: QSFP1_W],
v2e_tdata[4*ENET_W + 1*ENET_W +: QSFP1_W],
v2e_tdata[4*ENET_W + 0*ENET_W +: QSFP1_W] }),
.v2e_tlast (v2e_tlast [4 +: 4]),
.v2e_tvalid (v2e_tvalid[4 +: 4]),
.v2e_tready (v2e_tready[4 +: 4]),
// Misc
.eth_rx_irq (eth1_rx_irq),
.eth_tx_irq (eth1_tx_irq),
.device_id (device_id),
.rx_rec_clk_out (rx_rec_clk_out1),
.port_info_0 (qsfp_port_1_0_info),
.port_info_1 (qsfp_port_1_1_info),
.port_info_2 (qsfp_port_1_2_info),
.port_info_3 (qsfp_port_1_3_info),
.link_up (eth1_link_up),
.activity (eth1_activity)
);
`endif
//---------------------------------------------------------------------------
// Internal Ethernet Interface
@@ -2789,7 +2530,7 @@ module x4xx (
eth_ipv4_internal #(
.CHDR_W (DMA_W),
.NET_CHDR_W (NET_CHDR_W),
.NET_CHDR_W (CHDR_W),
.BYTE_MTU (BYTE_MTU),
.DWIDTH (REG_DWIDTH),
.AWIDTH (REG_AWIDTH),
@@ -3005,6 +2746,11 @@ module x4xx (
assign x4xx_core_version_info[COMPONENT_VERSIONS_SIZE*DB0_GPIO_IFC_INDEX +: COMPONENT_VERSIONS_SIZE] = db_gpio_ifc_version[0];
assign x4xx_core_version_info[COMPONENT_VERSIONS_SIZE*DB1_GPIO_IFC_INDEX +: COMPONENT_VERSIONS_SIZE] = db_gpio_ifc_version[1];
wire [127:0] qsfp0_port_info;
wire [127:0] qsfp1_port_info;
assign { qsfp_port_0_3_info, qsfp_port_0_2_info, qsfp_port_0_1_info, qsfp_port_0_0_info } = qsfp0_port_info;
assign { qsfp_port_1_3_info, qsfp_port_1_2_info, qsfp_port_1_1_info, qsfp_port_1_0_info } = qsfp1_port_info;
x4xx_core #(
.NUM_DBOARDS (NUM_DBOARDS),
.REG_DWIDTH (REG_DWIDTH),
@@ -3014,15 +2760,12 @@ module x4xx (
.NUM_CHANNELS (NUM_CHANNELS),
.NUM_TIMEKEEPERS (NUM_TIMEKEEPERS),
.CHDR_W (CHDR_W),
.DMA_W (DMA_W),
.NET_CHDR_W (NET_CHDR_W),
.ENET_W (ENET_W),
.ENET_WIDTHS (ENET_WIDTHS),
.MTU (CHDR_MTU),
.RFNOC_PROTOVER (RFNOC_PROTOVER),
.RADIO_SPC (RADIO_SPC),
.RF_BANDWIDTH (RF_BANDWIDTH)
) x4xx_core_i (
.areset (areset),
.radio_clk (radio_clk),
.radio_rst (radio_rst),
.radio_clk_2x (radio_clk_2x),
@@ -3063,6 +2806,142 @@ module x4xx (
.dram1_dq (DRAM1_DQ),
.dram1_dqs_t (DRAM1_DQS_p),
.dram1_dqs_c (DRAM1_DQS_n),
.qsfp0_refclk_p (MGT_REFCLK_LMK0_P),
.qsfp0_refclk_n (MGT_REFCLK_LMK0_N),
.qsfp0_dclk (clk100),
.qsfp0_tx_p (qsfp0_tx_p),
.qsfp0_tx_n (qsfp0_tx_n),
.qsfp0_rx_p (qsfp0_rx_p),
.qsfp0_rx_n (qsfp0_rx_n),
.qsfp0_recovered_clk (),
.qsfp0_device_id (device_id),
.qsfp0_rx_irq (eth0_rx_irq),
.qsfp0_tx_irq (eth0_tx_irq),
.qsfp0_port_info (qsfp0_port_info),
.qsfp0_link_up (eth0_link_up),
.qsfp0_activity (eth0_activity),
.qsfp0_axil_rst (clk40_rst),
.qsfp0_axil_clk (clk40),
.qsfp0_axil_awaddr (axi_qsfp0_awaddr),
.qsfp0_axil_awvalid (axi_qsfp0_awvalid),
.qsfp0_axil_awready (axi_qsfp0_awready),
.qsfp0_axil_wdata (axi_qsfp0_wdata),
.qsfp0_axil_wstrb (axi_qsfp0_wstrb),
.qsfp0_axil_wvalid (axi_qsfp0_wvalid),
.qsfp0_axil_wready (axi_qsfp0_wready),
.qsfp0_axil_bresp (axi_qsfp0_bresp),
.qsfp0_axil_bvalid (axi_qsfp0_bvalid),
.qsfp0_axil_bready (axi_qsfp0_bready),
.qsfp0_axil_araddr (axi_qsfp0_araddr),
.qsfp0_axil_arvalid (axi_qsfp0_arvalid),
.qsfp0_axil_arready (axi_qsfp0_arready),
.qsfp0_axil_rdata (axi_qsfp0_rdata),
.qsfp0_axil_rresp (axi_qsfp0_rresp),
.qsfp0_axil_rvalid (axi_qsfp0_rvalid),
.qsfp0_axil_rready (axi_qsfp0_rready),
.qsfp0_axi_rst (clk40_rst),
.qsfp0_axi_clk (clk40),
.qsfp0_axi_araddr (axi_hp0_araddr),
.qsfp0_axi_arburst (axi_hp0_arburst),
.qsfp0_axi_arcache (axi_hp0_arcache),
.qsfp0_axi_arlen (axi_hp0_arlen),
.qsfp0_axi_arlock (axi_hp0_arlock),
.qsfp0_axi_arprot (axi_hp0_arprot),
.qsfp0_axi_arqos (axi_hp0_arqos),
.qsfp0_axi_arready (axi_hp0_arready),
.qsfp0_axi_arsize (axi_hp0_arsize),
.qsfp0_axi_arvalid (axi_hp0_arvalid),
.qsfp0_axi_awaddr (axi_hp0_awaddr),
.qsfp0_axi_awburst (axi_hp0_awburst),
.qsfp0_axi_awcache (axi_hp0_awcache),
.qsfp0_axi_awlen (axi_hp0_awlen),
.qsfp0_axi_awlock (axi_hp0_awlock),
.qsfp0_axi_awprot (axi_hp0_awprot),
.qsfp0_axi_awqos (axi_hp0_awqos),
.qsfp0_axi_awready (axi_hp0_awready),
.qsfp0_axi_awsize (axi_hp0_awsize),
.qsfp0_axi_awvalid (axi_hp0_awvalid),
.qsfp0_axi_bready (axi_hp0_bready),
.qsfp0_axi_bresp (axi_hp0_bresp),
.qsfp0_axi_bvalid (axi_hp0_bvalid),
.qsfp0_axi_rdata (axi_hp0_rdata),
.qsfp0_axi_rlast (axi_hp0_rlast),
.qsfp0_axi_rready (axi_hp0_rready),
.qsfp0_axi_rresp (axi_hp0_rresp),
.qsfp0_axi_rvalid (axi_hp0_rvalid),
.qsfp0_axi_wdata (axi_hp0_wdata),
.qsfp0_axi_wlast (axi_hp0_wlast),
.qsfp0_axi_wready (axi_hp0_wready),
.qsfp0_axi_wstrb (axi_hp0_wstrb),
.qsfp0_axi_wvalid (axi_hp0_wvalid),
.qsfp1_refclk_p (MGT_REFCLK_LMK3_P),
.qsfp1_refclk_n (MGT_REFCLK_LMK3_N),
.qsfp1_dclk (clk100),
.qsfp1_tx_p (qsfp1_tx_p),
.qsfp1_tx_n (qsfp1_tx_n),
.qsfp1_rx_p (qsfp1_rx_p),
.qsfp1_rx_n (qsfp1_rx_n),
.qsfp1_recovered_clk (rx_rec_clk_out1),
.qsfp1_device_id (device_id),
.qsfp1_rx_irq (eth1_rx_irq),
.qsfp1_tx_irq (eth1_tx_irq),
.qsfp1_port_info (qsfp1_port_info),
.qsfp1_link_up (eth1_link_up),
.qsfp1_activity (eth1_activity),
.qsfp1_axil_rst (clk40_rst),
.qsfp1_axil_clk (clk40),
.qsfp1_axil_awaddr (axi_qsfp1_awaddr),
.qsfp1_axil_awvalid (axi_qsfp1_awvalid),
.qsfp1_axil_awready (axi_qsfp1_awready),
.qsfp1_axil_wdata (axi_qsfp1_wdata),
.qsfp1_axil_wstrb (axi_qsfp1_wstrb),
.qsfp1_axil_wvalid (axi_qsfp1_wvalid),
.qsfp1_axil_wready (axi_qsfp1_wready),
.qsfp1_axil_bresp (axi_qsfp1_bresp),
.qsfp1_axil_bvalid (axi_qsfp1_bvalid),
.qsfp1_axil_bready (axi_qsfp1_bready),
.qsfp1_axil_araddr (axi_qsfp1_araddr),
.qsfp1_axil_arvalid (axi_qsfp1_arvalid),
.qsfp1_axil_arready (axi_qsfp1_arready),
.qsfp1_axil_rdata (axi_qsfp1_rdata),
.qsfp1_axil_rresp (axi_qsfp1_rresp),
.qsfp1_axil_rvalid (axi_qsfp1_rvalid),
.qsfp1_axil_rready (axi_qsfp1_rready),
.qsfp1_axi_rst (clk40_rst),
.qsfp1_axi_clk (clk40),
.qsfp1_axi_araddr (axi_hp1_araddr),
.qsfp1_axi_arburst (axi_hp1_arburst),
.qsfp1_axi_arcache (axi_hp1_arcache),
.qsfp1_axi_arlen (axi_hp1_arlen),
.qsfp1_axi_arlock (axi_hp1_arlock),
.qsfp1_axi_arprot (axi_hp1_arprot),
.qsfp1_axi_arqos (axi_hp1_arqos),
.qsfp1_axi_arready (axi_hp1_arready),
.qsfp1_axi_arsize (axi_hp1_arsize),
.qsfp1_axi_arvalid (axi_hp1_arvalid),
.qsfp1_axi_awaddr (axi_hp1_awaddr),
.qsfp1_axi_awburst (axi_hp1_awburst),
.qsfp1_axi_awcache (axi_hp1_awcache),
.qsfp1_axi_awlen (axi_hp1_awlen),
.qsfp1_axi_awlock (axi_hp1_awlock),
.qsfp1_axi_awprot (axi_hp1_awprot),
.qsfp1_axi_awqos (axi_hp1_awqos),
.qsfp1_axi_awready (axi_hp1_awready),
.qsfp1_axi_awsize (axi_hp1_awsize),
.qsfp1_axi_awvalid (axi_hp1_awvalid),
.qsfp1_axi_bready (axi_hp1_bready),
.qsfp1_axi_bresp (axi_hp1_bresp),
.qsfp1_axi_bvalid (axi_hp1_bvalid),
.qsfp1_axi_rdata (axi_hp1_rdata),
.qsfp1_axi_rlast (axi_hp1_rlast),
.qsfp1_axi_rready (axi_hp1_rready),
.qsfp1_axi_rresp (axi_hp1_rresp),
.qsfp1_axi_rvalid (axi_hp1_rvalid),
.qsfp1_axi_wdata (axi_hp1_wdata),
.qsfp1_axi_wlast (axi_hp1_wlast),
.qsfp1_axi_wready (axi_hp1_wready),
.qsfp1_axi_wstrb (axi_hp1_wstrb),
.qsfp1_axi_wvalid (axi_hp1_wvalid),
.s_axi_aclk (clk40),
.s_axi_aresetn (clk40_rstn),
.s_axi_awaddr (axi_core_awaddr[REG_AWIDTH-1:0]),
@@ -3099,22 +2978,14 @@ module x4xx (
.tx_data (tx_data_iq),
.tx_stb (tx_stb),
.tx_running (tx_running),
.dmao_tdata (v2e_dma_tdata),
.dmao_tlast (v2e_dma_tlast),
.dmao_tvalid (v2e_dma_tvalid),
.dmao_tready (v2e_dma_tready),
.dmai_tdata (e2v_dma_tdata),
.dmai_tlast (e2v_dma_tlast),
.dmai_tvalid (e2v_dma_tvalid),
.dmai_tready (e2v_dma_tready),
.e2v_tdata (e2v_tdata),
.e2v_tlast (e2v_tlast),
.e2v_tvalid (e2v_tvalid),
.e2v_tready (e2v_tready),
.v2e_tdata (v2e_tdata),
.v2e_tlast (v2e_tlast),
.v2e_tvalid (v2e_tvalid),
.v2e_tready (v2e_tready),
.m_dma_tdata (v2e_dma_tdata),
.m_dma_tlast (v2e_dma_tlast),
.m_dma_tvalid (v2e_dma_tvalid),
.m_dma_tready (v2e_dma_tready),
.s_dma_tdata (e2v_dma_tdata),
.s_dma_tlast (e2v_dma_tlast),
.s_dma_tvalid (e2v_dma_tvalid),
.s_dma_tready (e2v_dma_tready),
.gpio_in_a (DIOA_FPGA),
.gpio_in_b (DIOB_FPGA),
.gpio_out_a (gpio_out_a),
+307 -106
View File
@@ -19,13 +19,6 @@
// NUM_CHANNELS : Total number of channels
// NUM_CH_PER_DB : Number of channels per daughterboard and radio core
// CHDR_W : CHDR width used by RFNoC
// DMA_W : Width of the DMA port interface
// NET_CHDR_W : CHDR width used by the network interface ports
// ENET_W : Width of the Ethernet buses (each port may have a unique
// width, but all signals have equal width for simplicity).
// ENET_WIDTHS : Actual width of each Ethernet port's interface. This is
// a packed array of 32-bit integers with port 0 in the
// right-most position.
// MTU : Log2 of maximum transmission unit in CHDR_W sized words
// RFNOC_PROTOVER : RFNoC protocol version (major[7:0], minor[7:0])
// RADIO_SPC : Number of samples per radio clock cycle
@@ -35,24 +28,21 @@
module x4xx_core #(
parameter NUM_DBOARDS = 2,
parameter REG_DWIDTH = 32,
parameter REG_AWIDTH = 32,
parameter CHDR_CLK_RATE = 200000000,
parameter NUM_CH_PER_DB = 2,
parameter NUM_CHANNELS = NUM_CH_PER_DB*NUM_DBOARDS,
parameter CHDR_W = 64,
parameter DMA_W = 64,
parameter NET_CHDR_W = 64,
parameter [ 31:0] ENET_W = 64,
parameter [32*8-1:0] ENET_WIDTHS = {8{ENET_W}},
parameter MTU = $clog2(8192 / (CHDR_W/8)),
parameter RFNOC_PROTOVER = {8'd1, 8'd0},
parameter RADIO_SPC = 1,
parameter NUM_TIMEKEEPERS = NUM_DBOARDS,
parameter RF_BANDWIDTH = 200
parameter NUM_DBOARDS = 2,
parameter REG_DWIDTH = 32,
parameter REG_AWIDTH = 32,
parameter CHDR_CLK_RATE = 200000000,
parameter NUM_CH_PER_DB = 2,
parameter NUM_CHANNELS = NUM_CH_PER_DB*NUM_DBOARDS,
parameter CHDR_W = 64,
parameter MTU = $clog2(8192 / (CHDR_W/8)),
parameter RFNOC_PROTOVER = {8'd1, 8'd0},
parameter RADIO_SPC = 1,
parameter NUM_TIMEKEEPERS = NUM_DBOARDS,
parameter RF_BANDWIDTH = 200
) (
// Clocks and resets
input wire areset,
input wire [NUM_DBOARDS-1:0] radio_clk,
input wire [NUM_DBOARDS-1:0] radio_rst,
input wire [NUM_DBOARDS-1:0] radio_clk_2x,
@@ -100,6 +90,146 @@ module x4xx_core #(
inout wire [ 7:0] dram1_dqs_t,
inout wire [ 7:0] dram1_dqs_c,
// QSFP Port 0
input wire qsfp0_refclk_p,
input wire qsfp0_refclk_n,
input wire qsfp0_dclk,
output wire [ 3:0] qsfp0_tx_p,
output wire [ 3:0] qsfp0_tx_n,
input wire [ 3:0] qsfp0_rx_p,
input wire [ 3:0] qsfp0_rx_n,
output wire qsfp0_recovered_clk,
input wire [ 15:0] qsfp0_device_id,
output wire [ 3:0] qsfp0_rx_irq,
output wire [ 3:0] qsfp0_tx_irq,
output wire [ 127:0] qsfp0_port_info,
output wire [ 3:0] qsfp0_link_up,
output wire [ 3:0] qsfp0_activity,
input wire qsfp0_axil_rst,
input wire qsfp0_axil_clk,
input wire [ 39:0] qsfp0_axil_awaddr,
input wire qsfp0_axil_awvalid,
output wire qsfp0_axil_awready,
input wire [ 31:0] qsfp0_axil_wdata,
input wire [ 3:0] qsfp0_axil_wstrb,
input wire qsfp0_axil_wvalid,
output wire qsfp0_axil_wready,
output wire [ 1:0] qsfp0_axil_bresp,
output wire qsfp0_axil_bvalid,
input wire qsfp0_axil_bready,
input wire [ 39:0] qsfp0_axil_araddr,
input wire qsfp0_axil_arvalid,
output wire qsfp0_axil_arready,
output wire [ 31:0] qsfp0_axil_rdata,
output wire [ 1:0] qsfp0_axil_rresp,
output wire qsfp0_axil_rvalid,
input wire qsfp0_axil_rready,
input wire qsfp0_axi_rst,
input wire qsfp0_axi_clk,
output wire [ 48:0] qsfp0_axi_araddr,
output wire [ 1:0] qsfp0_axi_arburst,
output wire [ 3:0] qsfp0_axi_arcache,
output wire [ 7:0] qsfp0_axi_arlen,
output wire [ 0:0] qsfp0_axi_arlock,
output wire [ 2:0] qsfp0_axi_arprot,
output wire [ 3:0] qsfp0_axi_arqos,
input wire qsfp0_axi_arready,
output wire [ 2:0] qsfp0_axi_arsize,
output wire qsfp0_axi_arvalid,
output wire [ 48:0] qsfp0_axi_awaddr,
output wire [ 1:0] qsfp0_axi_awburst,
output wire [ 3:0] qsfp0_axi_awcache,
output wire [ 7:0] qsfp0_axi_awlen,
output wire [ 0:0] qsfp0_axi_awlock,
output wire [ 2:0] qsfp0_axi_awprot,
output wire [ 3:0] qsfp0_axi_awqos,
input wire qsfp0_axi_awready,
output wire [ 2:0] qsfp0_axi_awsize,
output wire qsfp0_axi_awvalid,
output wire qsfp0_axi_bready,
input wire [ 1:0] qsfp0_axi_bresp,
input wire qsfp0_axi_bvalid,
input wire [ 127:0] qsfp0_axi_rdata,
input wire qsfp0_axi_rlast,
output wire qsfp0_axi_rready,
input wire [ 1:0] qsfp0_axi_rresp,
input wire qsfp0_axi_rvalid,
output wire [ 127:0] qsfp0_axi_wdata,
output wire qsfp0_axi_wlast,
input wire qsfp0_axi_wready,
output wire [ 15:0] qsfp0_axi_wstrb,
output wire qsfp0_axi_wvalid,
// QSFP Port 1
input wire qsfp1_refclk_p,
input wire qsfp1_refclk_n,
input wire qsfp1_dclk,
output wire [ 3:0] qsfp1_tx_p,
output wire [ 3:0] qsfp1_tx_n,
input wire [ 3:0] qsfp1_rx_p,
input wire [ 3:0] qsfp1_rx_n,
output wire qsfp1_recovered_clk,
input wire [ 15:0] qsfp1_device_id,
output wire [ 3:0] qsfp1_rx_irq,
output wire [ 3:0] qsfp1_tx_irq,
output wire [ 127:0] qsfp1_port_info,
output wire [ 3:0] qsfp1_link_up,
output wire [ 3:0] qsfp1_activity,
input wire qsfp1_axil_rst,
input wire qsfp1_axil_clk,
input wire [ 39:0] qsfp1_axil_awaddr,
input wire qsfp1_axil_awvalid,
output wire qsfp1_axil_awready,
input wire [ 31:0] qsfp1_axil_wdata,
input wire [ 3:0] qsfp1_axil_wstrb,
input wire qsfp1_axil_wvalid,
output wire qsfp1_axil_wready,
output wire [ 1:0] qsfp1_axil_bresp,
output wire qsfp1_axil_bvalid,
input wire qsfp1_axil_bready,
input wire [ 39:0] qsfp1_axil_araddr,
input wire qsfp1_axil_arvalid,
output wire qsfp1_axil_arready,
output wire [ 31:0] qsfp1_axil_rdata,
output wire [ 1:0] qsfp1_axil_rresp,
output wire qsfp1_axil_rvalid,
input wire qsfp1_axil_rready,
input wire qsfp1_axi_rst,
input wire qsfp1_axi_clk,
output wire [ 48:0] qsfp1_axi_araddr,
output wire [ 1:0] qsfp1_axi_arburst,
output wire [ 3:0] qsfp1_axi_arcache,
output wire [ 7:0] qsfp1_axi_arlen,
output wire [ 0:0] qsfp1_axi_arlock,
output wire [ 2:0] qsfp1_axi_arprot,
output wire [ 3:0] qsfp1_axi_arqos,
input wire qsfp1_axi_arready,
output wire [ 2:0] qsfp1_axi_arsize,
output wire qsfp1_axi_arvalid,
output wire [ 48:0] qsfp1_axi_awaddr,
output wire [ 1:0] qsfp1_axi_awburst,
output wire [ 3:0] qsfp1_axi_awcache,
output wire [ 7:0] qsfp1_axi_awlen,
output wire [ 0:0] qsfp1_axi_awlock,
output wire [ 2:0] qsfp1_axi_awprot,
output wire [ 3:0] qsfp1_axi_awqos,
input wire qsfp1_axi_awready,
output wire [ 2:0] qsfp1_axi_awsize,
output wire qsfp1_axi_awvalid,
output wire qsfp1_axi_bready,
input wire [ 1:0] qsfp1_axi_bresp,
input wire qsfp1_axi_bvalid,
input wire [ 127:0] qsfp1_axi_rdata,
input wire qsfp1_axi_rlast,
output wire qsfp1_axi_rready,
input wire [ 1:0] qsfp1_axi_rresp,
input wire qsfp1_axi_rvalid,
output wire [ 127:0] qsfp1_axi_wdata,
output wire qsfp1_axi_wlast,
input wire qsfp1_axi_wready,
output wire [ 15:0] qsfp1_axi_wstrb,
output wire qsfp1_axi_wvalid,
// AXI-Lite interface (for motherboard registers)
input s_axi_aclk,
input s_axi_aresetn,
@@ -144,26 +274,15 @@ module x4xx_core #(
output [ NUM_CHANNELS-1:0] tx_running,
// DMA
output [DMA_W-1:0] dmao_tdata,
output dmao_tlast,
output dmao_tvalid,
input dmao_tready,
output [CHDR_W-1:0] m_dma_tdata,
output m_dma_tlast,
output m_dma_tvalid,
input m_dma_tready,
input [DMA_W-1:0] dmai_tdata,
input dmai_tlast,
input dmai_tvalid,
output dmai_tready,
// e2v (Ethernet to CHDR)
output [ENET_W*8-1:0] v2e_tdata,
output [ 8-1:0] v2e_tvalid,
output [ 8-1:0] v2e_tlast,
input [ 8-1:0] v2e_tready,
// v2e (CHDR to Ethernet)
input [ENET_W*8-1:0] e2v_tdata,
input [ 8-1:0] e2v_tlast,
input [ 8-1:0] e2v_tvalid,
output [ 8-1:0] e2v_tready,
input [CHDR_W-1:0] s_dma_tdata,
input s_dma_tlast,
input s_dma_tvalid,
output s_dma_tready,
// GPIO to DIO board (Domain: rfnoc_ctrl_clk)
output wire [11:0] gpio_en_a,
@@ -303,7 +422,7 @@ module x4xx_core #(
x4xx_core_common #(
.CHDR_CLK_RATE (CHDR_CLK_RATE),
.CHDR_W (NET_CHDR_W),
.CHDR_W (CHDR_W),
.RFNOC_PROTOVER (RFNOC_PROTOVER),
.NUM_DBOARDS (NUM_DBOARDS),
.NUM_CH_PER_DB (NUM_CH_PER_DB),
@@ -673,29 +792,15 @@ module x4xx_core #(
assign tx_running = { tx_running1, tx_running0};
assign tx_data = { tx_data1, tx_data0};
localparam PORT_W = 512; // Set to max value; unused bits will be ignored.
localparam ENET0_W = ENET_WIDTHS[32*0 +: 32];
localparam ENET1_W = ENET_WIDTHS[32*1 +: 32];
localparam ENET2_W = ENET_WIDTHS[32*2 +: 32];
localparam ENET3_W = ENET_WIDTHS[32*3 +: 32];
localparam ENET4_W = ENET_WIDTHS[32*4 +: 32];
rfnoc_image_core #(
.CHDR_W (CHDR_W),
.PORT_W (PORT_W),
.ETH0_W (ENET0_W),
.ETH1_W (ENET1_W),
.ETH2_W (ENET2_W),
.ETH3_W (ENET3_W),
.ETH4_W (ENET4_W),
.DMA_W (DMA_W),
.MTU (MTU),
.PROTOVER (RFNOC_PROTOVER),
.RADIO_NIPC (RADIO_SPC)
) rfnoc_image_core_i (
.chdr_aclk (rfnoc_chdr_clk),
.ctrl_aclk (rfnoc_ctrl_clk),
.core_arst (rfnoc_ctrl_rst),
.core_arst (areset),
`ifdef X440
.radio0_clk (radio_clk[0]),
.radio0_2x_clk (radio_clk_2x[0]),
@@ -836,54 +941,150 @@ module x4xx_core #(
.dram1_m_axi_ruser (0),
.dram1_m_axi_rvalid (dram1_axi_rvalid),
.dram1_m_axi_rready (dram1_axi_rready),
.s_eth0_tdata (e2v_tdata [0*ENET_W +: ENET0_W]),
.s_eth0_tlast (e2v_tlast [0* 1 +: 1]),
.s_eth0_tvalid (e2v_tvalid [0* 1 +: 1]),
.s_eth0_tready (e2v_tready [0* 1 +: 1]),
.m_eth0_tdata (v2e_tdata [0*ENET_W +: ENET0_W]),
.m_eth0_tlast (v2e_tlast [0* 1 +: 1]),
.m_eth0_tvalid (v2e_tvalid [0* 1 +: 1]),
.m_eth0_tready (v2e_tready [0* 1 +: 1]),
.s_eth1_tdata (e2v_tdata [1*ENET_W +: ENET1_W]),
.s_eth1_tlast (e2v_tlast [1* 1 +: 1]),
.s_eth1_tvalid (e2v_tvalid [1* 1 +: 1]),
.s_eth1_tready (e2v_tready [1* 1 +: 1]),
.m_eth1_tdata (v2e_tdata [1*ENET_W +: ENET1_W]),
.m_eth1_tlast (v2e_tlast [1* 1 +: 1]),
.m_eth1_tvalid (v2e_tvalid [1* 1 +: 1]),
.m_eth1_tready (v2e_tready [1* 1 +: 1]),
.s_eth2_tdata (e2v_tdata [2*ENET_W +: ENET2_W]),
.s_eth2_tlast (e2v_tlast [2* 1 +: 1]),
.s_eth2_tvalid (e2v_tvalid [2* 1 +: 1]),
.s_eth2_tready (e2v_tready [2* 1 +: 1]),
.m_eth2_tdata (v2e_tdata [2*ENET_W +: ENET2_W]),
.m_eth2_tlast (v2e_tlast [2* 1 +: 1]),
.m_eth2_tvalid (v2e_tvalid [2* 1 +: 1]),
.m_eth2_tready (v2e_tready [2* 1 +: 1]),
.s_eth3_tdata (e2v_tdata [3*ENET_W +: ENET3_W]),
.s_eth3_tlast (e2v_tlast [3* 1 +: 1]),
.s_eth3_tvalid (e2v_tvalid [3* 1 +: 1]),
.s_eth3_tready (e2v_tready [3* 1 +: 1]),
.m_eth3_tdata (v2e_tdata [3*ENET_W +: ENET3_W]),
.m_eth3_tlast (v2e_tlast [3* 1 +: 1]),
.m_eth3_tvalid (v2e_tvalid [3* 1 +: 1]),
.m_eth3_tready (v2e_tready [3* 1 +: 1]),
.s_eth4_tdata (e2v_tdata [4*ENET_W +: ENET4_W]),
.s_eth4_tlast (e2v_tlast [4* 1 +: 1]),
.s_eth4_tvalid (e2v_tvalid [4* 1 +: 1]),
.s_eth4_tready (e2v_tready [4* 1 +: 1]),
.m_eth4_tdata (v2e_tdata [4*ENET_W +: ENET4_W]),
.m_eth4_tlast (v2e_tlast [4* 1 +: 1]),
.m_eth4_tvalid (v2e_tvalid [4* 1 +: 1]),
.m_eth4_tready (v2e_tready [4* 1 +: 1]),
.s_dma_tdata (dmai_tdata),
.s_dma_tlast (dmai_tlast),
.s_dma_tvalid (dmai_tvalid),
.s_dma_tready (dmai_tready),
.m_dma_tdata (dmao_tdata),
.m_dma_tlast (dmao_tlast),
.m_dma_tvalid (dmao_tvalid),
.m_dma_tready (dmao_tready)
.qsfp0_refclk_p (qsfp0_refclk_p),
.qsfp0_refclk_n (qsfp0_refclk_n),
.qsfp0_dclk (qsfp0_dclk),
.qsfp0_tx_p (qsfp0_tx_p),
.qsfp0_tx_n (qsfp0_tx_n),
.qsfp0_rx_p (qsfp0_rx_p),
.qsfp0_rx_n (qsfp0_rx_n),
.qsfp0_recovered_clk (qsfp0_recovered_clk),
.qsfp0_device_id (qsfp0_device_id),
.qsfp0_rx_irq (qsfp0_rx_irq),
.qsfp0_tx_irq (qsfp0_tx_irq),
.qsfp0_port_info (qsfp0_port_info),
.qsfp0_link_up (qsfp0_link_up),
.qsfp0_activity (qsfp0_activity),
.qsfp0_axil_rst (qsfp0_axil_rst),
.qsfp0_axil_clk (qsfp0_axil_clk),
.qsfp0_axil_awaddr (qsfp0_axil_awaddr),
.qsfp0_axil_awvalid (qsfp0_axil_awvalid),
.qsfp0_axil_awready (qsfp0_axil_awready),
.qsfp0_axil_wdata (qsfp0_axil_wdata),
.qsfp0_axil_wstrb (qsfp0_axil_wstrb),
.qsfp0_axil_wvalid (qsfp0_axil_wvalid),
.qsfp0_axil_wready (qsfp0_axil_wready),
.qsfp0_axil_bresp (qsfp0_axil_bresp),
.qsfp0_axil_bvalid (qsfp0_axil_bvalid),
.qsfp0_axil_bready (qsfp0_axil_bready),
.qsfp0_axil_araddr (qsfp0_axil_araddr),
.qsfp0_axil_arvalid (qsfp0_axil_arvalid),
.qsfp0_axil_arready (qsfp0_axil_arready),
.qsfp0_axil_rdata (qsfp0_axil_rdata),
.qsfp0_axil_rresp (qsfp0_axil_rresp),
.qsfp0_axil_rvalid (qsfp0_axil_rvalid),
.qsfp0_axil_rready (qsfp0_axil_rready),
.qsfp0_axi_rst (qsfp0_axi_rst),
.qsfp0_axi_clk (qsfp0_axi_clk),
.qsfp0_axi_araddr (qsfp0_axi_araddr),
.qsfp0_axi_arburst (qsfp0_axi_arburst),
.qsfp0_axi_arcache (qsfp0_axi_arcache),
.qsfp0_axi_arlen (qsfp0_axi_arlen),
.qsfp0_axi_arlock (qsfp0_axi_arlock),
.qsfp0_axi_arprot (qsfp0_axi_arprot),
.qsfp0_axi_arqos (qsfp0_axi_arqos),
.qsfp0_axi_arready (qsfp0_axi_arready),
.qsfp0_axi_arsize (qsfp0_axi_arsize),
.qsfp0_axi_arvalid (qsfp0_axi_arvalid),
.qsfp0_axi_awaddr (qsfp0_axi_awaddr),
.qsfp0_axi_awburst (qsfp0_axi_awburst),
.qsfp0_axi_awcache (qsfp0_axi_awcache),
.qsfp0_axi_awlen (qsfp0_axi_awlen),
.qsfp0_axi_awlock (qsfp0_axi_awlock),
.qsfp0_axi_awprot (qsfp0_axi_awprot),
.qsfp0_axi_awqos (qsfp0_axi_awqos),
.qsfp0_axi_awready (qsfp0_axi_awready),
.qsfp0_axi_awsize (qsfp0_axi_awsize),
.qsfp0_axi_awvalid (qsfp0_axi_awvalid),
.qsfp0_axi_bready (qsfp0_axi_bready),
.qsfp0_axi_bresp (qsfp0_axi_bresp),
.qsfp0_axi_bvalid (qsfp0_axi_bvalid),
.qsfp0_axi_rdata (qsfp0_axi_rdata),
.qsfp0_axi_rlast (qsfp0_axi_rlast),
.qsfp0_axi_rready (qsfp0_axi_rready),
.qsfp0_axi_rresp (qsfp0_axi_rresp),
.qsfp0_axi_rvalid (qsfp0_axi_rvalid),
.qsfp0_axi_wdata (qsfp0_axi_wdata),
.qsfp0_axi_wlast (qsfp0_axi_wlast),
.qsfp0_axi_wready (qsfp0_axi_wready),
.qsfp0_axi_wstrb (qsfp0_axi_wstrb),
.qsfp0_axi_wvalid (qsfp0_axi_wvalid),
.qsfp1_refclk_p (qsfp1_refclk_p),
.qsfp1_refclk_n (qsfp1_refclk_n),
.qsfp1_dclk (qsfp1_dclk),
.qsfp1_tx_p (qsfp1_tx_p),
.qsfp1_tx_n (qsfp1_tx_n),
.qsfp1_rx_p (qsfp1_rx_p),
.qsfp1_rx_n (qsfp1_rx_n),
.qsfp1_recovered_clk (qsfp1_recovered_clk),
.qsfp1_device_id (qsfp1_device_id),
.qsfp1_rx_irq (qsfp1_rx_irq),
.qsfp1_tx_irq (qsfp1_tx_irq),
.qsfp1_port_info (qsfp1_port_info),
.qsfp1_link_up (qsfp1_link_up),
.qsfp1_activity (qsfp1_activity),
.qsfp1_axil_rst (qsfp1_axil_rst),
.qsfp1_axil_clk (qsfp1_axil_clk),
.qsfp1_axil_awaddr (qsfp1_axil_awaddr),
.qsfp1_axil_awvalid (qsfp1_axil_awvalid),
.qsfp1_axil_awready (qsfp1_axil_awready),
.qsfp1_axil_wdata (qsfp1_axil_wdata),
.qsfp1_axil_wstrb (qsfp1_axil_wstrb),
.qsfp1_axil_wvalid (qsfp1_axil_wvalid),
.qsfp1_axil_wready (qsfp1_axil_wready),
.qsfp1_axil_bresp (qsfp1_axil_bresp),
.qsfp1_axil_bvalid (qsfp1_axil_bvalid),
.qsfp1_axil_bready (qsfp1_axil_bready),
.qsfp1_axil_araddr (qsfp1_axil_araddr),
.qsfp1_axil_arvalid (qsfp1_axil_arvalid),
.qsfp1_axil_arready (qsfp1_axil_arready),
.qsfp1_axil_rdata (qsfp1_axil_rdata),
.qsfp1_axil_rresp (qsfp1_axil_rresp),
.qsfp1_axil_rvalid (qsfp1_axil_rvalid),
.qsfp1_axil_rready (qsfp1_axil_rready),
.qsfp1_axi_rst (qsfp1_axi_rst),
.qsfp1_axi_clk (qsfp1_axi_clk),
.qsfp1_axi_araddr (qsfp1_axi_araddr),
.qsfp1_axi_arburst (qsfp1_axi_arburst),
.qsfp1_axi_arcache (qsfp1_axi_arcache),
.qsfp1_axi_arlen (qsfp1_axi_arlen),
.qsfp1_axi_arlock (qsfp1_axi_arlock),
.qsfp1_axi_arprot (qsfp1_axi_arprot),
.qsfp1_axi_arqos (qsfp1_axi_arqos),
.qsfp1_axi_arready (qsfp1_axi_arready),
.qsfp1_axi_arsize (qsfp1_axi_arsize),
.qsfp1_axi_arvalid (qsfp1_axi_arvalid),
.qsfp1_axi_awaddr (qsfp1_axi_awaddr),
.qsfp1_axi_awburst (qsfp1_axi_awburst),
.qsfp1_axi_awcache (qsfp1_axi_awcache),
.qsfp1_axi_awlen (qsfp1_axi_awlen),
.qsfp1_axi_awlock (qsfp1_axi_awlock),
.qsfp1_axi_awprot (qsfp1_axi_awprot),
.qsfp1_axi_awqos (qsfp1_axi_awqos),
.qsfp1_axi_awready (qsfp1_axi_awready),
.qsfp1_axi_awsize (qsfp1_axi_awsize),
.qsfp1_axi_awvalid (qsfp1_axi_awvalid),
.qsfp1_axi_bready (qsfp1_axi_bready),
.qsfp1_axi_bresp (qsfp1_axi_bresp),
.qsfp1_axi_bvalid (qsfp1_axi_bvalid),
.qsfp1_axi_rdata (qsfp1_axi_rdata),
.qsfp1_axi_rlast (qsfp1_axi_rlast),
.qsfp1_axi_rready (qsfp1_axi_rready),
.qsfp1_axi_rresp (qsfp1_axi_rresp),
.qsfp1_axi_rvalid (qsfp1_axi_rvalid),
.qsfp1_axi_wdata (qsfp1_axi_wdata),
.qsfp1_axi_wlast (qsfp1_axi_wlast),
.qsfp1_axi_wready (qsfp1_axi_wready),
.qsfp1_axi_wstrb (qsfp1_axi_wstrb),
.qsfp1_axi_wvalid (qsfp1_axi_wvalid),
.s_dma_tdata (s_dma_tdata),
.s_dma_tlast (s_dma_tlast),
.s_dma_tvalid (s_dma_tvalid),
.s_dma_tready (s_dma_tready),
.m_dma_tdata (m_dma_tdata),
.m_dma_tlast (m_dma_tlast),
.m_dma_tvalid (m_dma_tvalid),
.m_dma_tready (m_dma_tready)
);
endmodule
-426
View File
@@ -1,426 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_mgt_io_core
//
// Description:
//
// Encapsulates the PCS/PMA, the MAC layer and the control interface
// for 10GbE, and 100Gbe.
//
// Parameters:
//
// PROTOCOL : Indicates the protocol to use for each of the 4 QSFP lanes.
// See x4xx_mgt_types.vh for possible values.
// REG_BASE : Base address for internal registers
// REG_DWIDTH : Register data width
// REG_AWIDTH : Register address width
// PORTNUM : Port number, to distinguish between multiple QSFP ports
// LANENUM : Lane number
//
`include "./x4xx_mgt_types.vh"
module x4xx_mgt_io_core #(
parameter PROTOCOL = `MGT_100GbE,
parameter [13:0] REG_BASE = 14'h0,
parameter REG_DWIDTH = 32,
parameter REG_AWIDTH = 14,
parameter [ 7:0] PORTNUM = 8'd0,
parameter LANENUM = 0
) (
// Resets
input logic areset,
input logic bus_rst,
output logic mgt_rst,
// Clocks
input logic clk100,
input logic bus_clk,
input logic refclk_p,
input logic refclk_n,
output logic mgt_clk,
// QSFP high-speed IO
output logic [3:0] tx_p,
output logic [3:0] tx_n,
input logic [3:0] rx_p,
input logic [3:0] rx_n,
// Common signals for single lane 10 GbE
output logic [0:0] qpll0_reset,
input logic [0:0] qpll0_lock,
input logic [0:0] qpll0_clk,
input logic [0:0] qpll0_refclk,
output logic [0:0] qpll1_reset,
input logic [0:0] qpll1_lock,
input logic [0:0] qpll1_clk,
input logic [0:0] qpll1_refclk,
// AXI-Lite
AxiLiteIf.slave m_axi_mac,
// Data port
// Interface clocks on mgt_tx and mgt_rx are NOT used (logic uses mgt_clk).
AxiStreamIf.slave mgt_tx,
AxiStreamIf.master mgt_rx,
input logic mgt_pause_req,
// Register port
input logic reg_wr_req,
input logic [REG_AWIDTH-1:0] reg_wr_addr,
input logic [REG_DWIDTH-1:0] reg_wr_data,
input logic reg_rd_req,
input logic [REG_AWIDTH-1:0] reg_rd_addr,
output logic reg_rd_resp,
output logic [REG_DWIDTH-1:0] reg_rd_data,
// Misc.
output logic rx_rec_clk_out,
output logic [31:0] port_info,
output logic link_up,
output logic activity
);
import PkgAxiLite::*;
//---------------------------------------------------------------------------
// Registers
//---------------------------------------------------------------------------
localparam [7:0] COMPAT_NUM = 8'd2;
// Common registers
localparam REG_PORT_INFO = REG_BASE + 'h0;
localparam REG_MAC_CTRL_STATUS = REG_BASE + 'h4;
localparam REG_PHY_CTRL_STATUS = REG_BASE + 'h8;
localparam REG_MAC_LED_CTL = REG_BASE + 'hC;
// Ethernet specific
localparam REG_ETH_MDIO_BASE = REG_BASE + 'h10;
// Aurora specific
localparam REG_AURORA_OVERRUNS = REG_BASE + 'h20;
localparam REG_CHECKSUM_ERRORS = REG_BASE + 'h24;
localparam REG_BIST_CHECKER_SAMPS = REG_BASE + 'h28;
localparam REG_BIST_CHECKER_ERRORS = REG_BASE + 'h2C;
localparam [ 1:0] MAC_LED_CTRL_RST_VAL = 2'h0;
localparam [ 7:0] MGT_PROTOCOL = PROTOCOL;
localparam [31:0] MAC_CTRL_RST_VAL =
PROTOCOL == `MGT_100GbE ? {31'h0, 1'b1} : // Auto-connect enabled by default
PROTOCOL == `MGT_WhiteRabbit ? 32'h0 :
PROTOCOL == `MGT_Aurora ? 32'h0 :
PROTOCOL == `MGT_10GbE ? {31'h0, 1'b1} : // Tx enabled by default
PROTOCOL == `MGT_1GbE ? {31'h0, 1'b1} : // Tx enabled by default
32'h0;
localparam [31:0] PHY_CTRL_RST_VAL =
PROTOCOL == `MGT_100GbE ? 32'h0 : // Unused
PROTOCOL == `MGT_WhiteRabbit ? 32'h0 : // Unused
PROTOCOL == `MGT_Aurora ? 32'h0 :
PROTOCOL == `MGT_10GbE ? 32'h0 : // Unused
PROTOCOL == `MGT_1GbE ? 32'h0 :
32'h0;
// Writable registers
logic [31:0] mac_ctrl = MAC_CTRL_RST_VAL;
logic [31:0] phy_ctrl = PHY_CTRL_RST_VAL;
logic [ 1:0] mac_led_ctl = MAC_LED_CTRL_RST_VAL;
always @(posedge bus_clk) begin
if (bus_rst) begin
mac_ctrl <= MAC_CTRL_RST_VAL;
phy_ctrl <= PHY_CTRL_RST_VAL;
mac_led_ctl <= MAC_LED_CTRL_RST_VAL;
end else if (reg_wr_req) begin
case(reg_wr_addr)
REG_MAC_CTRL_STATUS:
mac_ctrl <= reg_wr_data;
REG_PHY_CTRL_STATUS:
phy_ctrl <= reg_wr_data;
REG_MAC_LED_CTL:
mac_led_ctl <= reg_wr_data[1:0];
endcase
end
end
// Readable registers
logic [31:0] overruns;
logic [31:0] checksum_errors;
logic [47:0] bist_checker_samps;
logic [47:0] bist_checker_errors;
logic [31:0] mac_status, phy_status;
logic [31:0] mac_status_bclk, phy_status_bclk;
logic activity_bclk, link_up_bclk;
logic [31:0] port_info_bclk;
// readback on m_axi.clk outside this core
assign port_info = {COMPAT_NUM, 6'h0, activity, link_up, MGT_PROTOCOL, PORTNUM};
assign port_info_bclk = {COMPAT_NUM, 6'h0, activity_bclk, link_up_bclk, MGT_PROTOCOL, PORTNUM};
always @(posedge bus_clk) begin
// No reset handling needed for readback
if (reg_rd_req) begin
reg_rd_resp <= 1'b1;
case(reg_rd_addr)
REG_PORT_INFO:
reg_rd_data <= port_info_bclk;
REG_MAC_CTRL_STATUS:
reg_rd_data <= mac_status_bclk;
REG_PHY_CTRL_STATUS:
reg_rd_data <= phy_status_bclk;
REG_MAC_LED_CTL:
reg_rd_data <= {30'd0, mac_led_ctl};
REG_AURORA_OVERRUNS:
reg_rd_data <= overruns;
REG_CHECKSUM_ERRORS:
reg_rd_data <= checksum_errors;
REG_BIST_CHECKER_SAMPS:
reg_rd_data <= bist_checker_samps[47:16]; // Scale num samples by 2^16
REG_BIST_CHECKER_ERRORS:
reg_rd_data <= bist_checker_errors[31:0]; // Don't scale errors
default:
begin
reg_rd_data <= 32'd0;
reg_rd_resp <= 1'b0;
end
endcase
end if (reg_rd_resp) begin
reg_rd_resp <= 1'b0;
end
end
synchronizer #(
.STAGES(2), .WIDTH(32), .INITIAL_VAL(32'h0)
) synchronizer_mac_status (
.clk(bus_clk), .rst(1'b0), .in(mac_status), .out(mac_status_bclk)
);
synchronizer #(
.STAGES(2), .WIDTH(32), .INITIAL_VAL(32'h0)
) synchronizer_phy_status (
.clk(bus_clk), .rst(1'b0), .in(phy_status), .out(phy_status_bclk)
);
logic link_up_mgtclk;
logic wr_activity = 0;
if (PROTOCOL == `MGT_10GbE) begin : core_10g
//-------------------------------------------------------------------------
// 10 GbE Interface
//-------------------------------------------------------------------------
eth_10g eth_10g_i (
.areset (areset),
// Free-running 100 MHz clock used for InitClk and AxiLite to MAC
.clk100 (clk100),
// Quad Info
.qpll0_refclk (qpll0_refclk),
.qpll0_clk (qpll0_clk),
.qpll0_lock (qpll0_lock),
.qpll0_reset (qpll0_reset),
.qpll1_refclk (qpll1_refclk),
.qpll1_clk (qpll1_clk),
.qpll1_lock (qpll1_lock),
.qpll1_reset (qpll1_reset),
// Recovered clock for export
.rx_rec_clk_out (rx_rec_clk_out),
// MGT TX/RX differential signals
.tx_p (tx_p[LANENUM]),
.tx_n (tx_n[LANENUM]),
.rx_p (rx_p[LANENUM]),
.rx_n (rx_n[LANENUM]),
// 156.25 MHz clock
.mgt_clk (mgt_clk),
.mgt_rst (mgt_rst),
// AXI Stream TX Interface
.mgt_tx (mgt_tx),
// AXI Stream RX Interface
// There is no RX TREADY signal support in the IP. Received data has to
// be read immediately or it is lost. TUSER indicates an error on
// received packet.
.mgt_rx (mgt_rx),
// AXI-Lite bus for tie off
.mgt_axil (m_axi_mac),
// LEDs of QSFP28 port
.phy_status (phy_status),
.mac_ctrl (mac_ctrl),
.mac_status (mac_status),
.phy_reset (),
.link_up (link_up_mgtclk)
);
always_comb begin : eth_10g_tieoff
overruns = 0;
checksum_errors = 0;
bist_checker_samps = 0;
bist_checker_errors = 0;
end : eth_10g_tieoff
end else if (PROTOCOL == `MGT_100GbE) begin : core_100g
//-------------------------------------------------------------------------
// 100 GbE Interface
//-------------------------------------------------------------------------
eth_100g eth_100g_i (
.areset (areset),
// Free-running 100 MHz clock used for InitClk and AxiLite to MAC
.clk100 (clk100),
// MGT Reference Clock 100/125/156.25/161.1328125 MHz
.refclk_p (refclk_p),
.refclk_n (refclk_n),
// Recovered clock for export
.rx_rec_clk_out (rx_rec_clk_out),
// MGT TX/RX differential signals
.tx_p (tx_p),
.tx_n (tx_n),
.rx_p (rx_p),
.rx_n (rx_n),
// 322.26666 MHz clock generated by 100G PHY from RefClock
.mgt_clk (mgt_clk),
.mgt_rst (mgt_rst),
.mgt_pause_req (mgt_pause_req),
// AXI Stream TX Interface
.mgt_tx (mgt_tx),
// AXI Stream RX Interface
// There is no RX TREADY signal support in the IP. Received data has to
// be read immediately or it is lost. TUSER indicates an error on
// received packet.
.mgt_rx (mgt_rx),
.mgt_axil (m_axi_mac),
// LEDs of QSFP28 port
.phy_status (phy_status),
.mac_status (mac_status),
.mac_ctrl (mac_ctrl),
.phy_reset (),
.link_up (link_up_mgtclk)
);
always_comb begin : eth_100g_tieoff
overruns = 0;
checksum_errors = 0;
bist_checker_samps = 0;
bist_checker_errors = 0;
qpll0_reset = 0;
qpll1_reset = 0;
end : eth_100g_tieoff
end else if (PROTOCOL == `MGT_Aurora) begin : core_aurora
Aurora_not_yet_supported();
always_comb begin : aurrora_tieoff
m_axi_mac.drive_read_resp(.resp(SLVERR),.data(0));
m_axi_mac.drive_write_resp(.resp(SLVERR));
m_axi_mac.arready = 1'b1;
m_axi_mac.awready = 1'b1;
m_axi_mac.wready = 1'b1;
phy_status = 'h0;
mac_status = 'h0;
link_up_mgtclk = 1'b0;
overruns = 0;
checksum_errors = 0;
bist_checker_samps = 0;
bist_checker_errors = 0;
rx_rec_clk_out = 0;
qpll0_reset = 0;
qpll1_reset = 0;
end : aurrora_tieoff
end else begin : core_disabled
//-------------------------------------------------------------------------
// Port Disabled
//-------------------------------------------------------------------------
assign mgt_clk = bus_clk;
assign mgt_rst = bus_rst;
always_comb begin : disabled_tieoff
m_axi_mac.drive_read_resp(.resp(SLVERR),.data(0));
m_axi_mac.drive_write_resp(.resp(SLVERR));
m_axi_mac.arready = 1'b1;
m_axi_mac.awready = 1'b1;
m_axi_mac.wready = 1'b1;
phy_status = 'h0;
mac_status = 'h0;
link_up_mgtclk = 1'b0;
mgt_tx.tready = 1'b1;
mgt_rx.tdata = 64'h0;
mgt_rx.tuser = 4'h0;
mgt_rx.tlast = 1'b0;
mgt_rx.tvalid = 1'b0;
mgt_rx.tkeep = 'b0;
overruns = 0;
checksum_errors = 0;
bist_checker_samps = 0;
bist_checker_errors = 0;
rx_rec_clk_out = 0;
tx_p = 0;
tx_n = 0;
qpll0_reset = 0;
qpll1_reset = 0;
end : disabled_tieoff
end
//---------------------------------------------------------------------------
// Activity Detector
//---------------------------------------------------------------------------
logic identify_enable,identify_value;
logic activity_mgtclk, activity_int;
always_comb begin
identify_enable = mac_led_ctl[0];
identify_value = mac_led_ctl[1];
end
pulse_stretch pulse_stretch_activity_i (
.clk (mgt_clk),
.rst (mgt_rst | ~link_up_mgtclk),
.pulse ((mgt_tx.tvalid & mgt_tx.tready) | (mgt_rx.tvalid & mgt_rx.tready)),
.pulse_stretched (activity_mgtclk)
);
synchronizer #(
.WIDTH (2),
.STAGES (1)
) synchronizer_lnk_act_bclk (
.clk (bus_clk),
.rst (bus_rst),
.in ({link_up_mgtclk, activity_mgtclk}),
.out ({link_up_bclk, activity_int})
);
always @ (posedge bus_clk) begin
activity_bclk <= identify_enable ? identify_value : activity_int;
end
synchronizer #(
.WIDTH (2),
.STAGES (1)
) synchronizer_lnk_act_aclk (
.clk (m_axi_mac.clk),
.rst (m_axi_mac.rst),
.in ({link_up_bclk, activity_bclk}),
.out ({link_up, activity})
);
endmodule
-15
View File
@@ -1,15 +0,0 @@
//
// Copyright 2021 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_mgt_type.vh
// Description: Enumerations for types of MGT to be used with the X4XX
//
`define MGT_100GbE 5
`define MGT_WhiteRabbit 4
`define MGT_Aurora 3
`define MGT_10GbE 2
`define MGT_1GbE 1
`define MGT_Disabled 0
-570
View File
@@ -1,570 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_qsfp_wrapper
//
// Description:
//
// Consolidates the logic necessary for a QSFP port, depending on the
// requested protocol.
//
// Parameters:
//
// PROTOCOL : Indicates the protocol to use for each of the 4 QSFP
// lanes. See x4xx_mgt_types.vh for possible values.
// CHDR_W : CHDR bus width
// NET_CHDR_W : CHDR width used over the network connection
// BYTE_MTU : Transport MTU in bytes
// PORTNUM : Port number to distinguish multiple QSFP ports
// NODE_INST : RFNoC transport adapter node instance for the first port
// RFNOC_PROTOVER : RFNoC protocol version for IPv4 interface
//
`include "./x4xx_mgt_types.vh"
module x4xx_qsfp_wrapper #(
// Must be a value defined in x4xx_mgt_types.vh
parameter integer PROTOCOL [3:0] = {`MGT_Disabled,
`MGT_Disabled,
`MGT_Disabled,
`MGT_Disabled},
parameter CHDR_W = 64,
parameter NET_CHDR_W = CHDR_W,
parameter BYTE_MTU = $clog2(8*1024),
parameter [ 7:0] PORTNUM = 8'd0,
parameter NODE_INST = 0,
parameter [15:0] RFNOC_PROTOVER = {8'd1, 8'd0}
)(
// Resets
input logic areset,
input logic bus_rst,
input logic clk40_rst,
// Clocks
input logic refclk_p,
input logic refclk_n,
input logic clk100,
input logic bus_clk,
// AXI-Lite register access
AxiLiteIf.slave s_axi,
// Ethernet DMA AXI to PS memory
AxiIf.master axi_hp,
// MGT high-speed IO
output logic [3:0] tx_p,
output logic [3:0] tx_n,
input logic [3:0] rx_p,
input logic [3:0] rx_n,
// CHDR router interface
AxiStreamIf.master e2v [4],
AxiStreamIf.slave v2e [4],
// ETH DMA IRQs
output logic [3:0] eth_rx_irq,
output logic [3:0] eth_tx_irq,
// Misc.
output logic rx_rec_clk_out,
input logic [15:0] device_id,
output logic [3:0][31:0] port_info,
output logic [3:0] link_up,
output logic [3:0] activity
);
import PkgAxiLite::*;
localparam REG_BASE_SFP_IO = 14'h0;
localparam REG_BASE_ETH_SWITCH = 14'h1000;
localparam CPU_W = 64; // Must match axi_eth_dma IP
localparam CPU_USER_W = $clog2(CPU_W/8)+1;
localparam CHDR_USER_W = $clog2(CHDR_W/8);
localparam REG_DWIDTH = 32;
localparam REG_AWIDTH_MISC = 14;
localparam logic [3:0] DISABLED = { PROTOCOL[3] == `MGT_Disabled,
PROTOCOL[2] == `MGT_Disabled,
PROTOCOL[1] == `MGT_Disabled,
PROTOCOL[0] == `MGT_Disabled };
localparam logic [3:0] IS10GBE = { PROTOCOL[3] == `MGT_10GbE,
PROTOCOL[2] == `MGT_10GbE,
PROTOCOL[1] == `MGT_10GbE,
PROTOCOL[0] == `MGT_10GbE };
localparam logic [3:0] IS100GBE = { 3'b0,PROTOCOL[0] == `MGT_100GbE };
localparam logic [3:0] ISAURORA = { 3'b0,PROTOCOL[0] == `MGT_Aurora };
`include "../../lib/axi4_sv/axi.vh"
`include "../../lib/axi4lite_sv/axi_lite.vh"
//---------------------------------------------------------------------------
// Interfaces
//---------------------------------------------------------------------------
// AXI-Lite interface
AxiLiteIf #(REG_DWIDTH,40)
m_axi_dma[3:0] (s_axi.clk, s_axi.rst);
// 0x0000-0x3FFF - Bottom goes to XGE top goes to UIO
AxiLiteIf #(REG_DWIDTH,40)
m_axi_misc[3:0] (s_axi.clk, s_axi.rst);
AxiLiteIf_v #(REG_DWIDTH,REG_AWIDTH_MISC)
m_axi_misc_v[3:0] (s_axi.clk, s_axi.rst);
// 0x4000-0x5FFF - Goes to 100G Mac
AxiLiteIf #(REG_DWIDTH,40)
m_axi_mac[3:0] (s_axi.clk, s_axi.rst);
// AXI (Full) for DMA back to CPU memory
AxiIf #(128,49)
axi_hp_dma[3:0] (s_axi.clk, s_axi.rst);
//---------------------------------------------------------------------------
// AXI Interconnect
//---------------------------------------------------------------------------
//
// Break the incoming register request into 12 different spaces:
//
// 0x0_0000 - dma0
// 0x0_8000 - misc0 - +0x0000 NIXGE
// +0x2000 UIO
// 0x0_C000 - mac0
//
// 0x1_0000 - dma1
// 0x1_8000 - misc1 - +0x0000 NIXGE
// +0x2000 UIO
// 0x1_C000 - mac1
//
// 0x2_0000 - dma2
// 0x2_8000 - misc2 - +0x0000 NIXGE
// +0x2000 UIO
// 0x2_C000 - mac2
//
// 0x3_0000 - dma3
// 0x3_8000 - misc3 - +0x0000 NIXGE
// +0x2000 UIO
// 0x3_C000 - mac3
//
//---------------------------------------------------------------------------
axi_interconnect_eth axi_interconnect_eth_i (
.s_axi_eth (s_axi),
.m_axi_dma (m_axi_dma),
.m_axi_misc (m_axi_misc),
.m_axi_mac (m_axi_mac)
);
//---------------------------------------------------------------------------
// Map DMA Engine Masters to CPU Memory Port
//---------------------------------------------------------------------------
// Everything Disabled
if (DISABLED == 4'b1111) begin : axi_hp_noconnect
always_comb begin
axi_hp.drive_read_idle();
axi_hp.drive_aw_idle();
axi_hp.drive_w_idle();
axi_hp.bready = 1'b0;
axi_hp.rready = 1'b0;
end
end : axi_hp_noconnect else
// Only port0 Enabled
if (DISABLED == 4'b1110) begin : axi_hp_directconnect
always_comb begin
`AXI4_ASSIGN(axi_hp,axi_hp_dma[0])
axi_hp_dma[1].wready = 1'b0;
axi_hp_dma[2].wready = 1'b0;
axi_hp_dma[3].wready = 1'b0;
axi_hp_dma[1].awready = 1'b0;
axi_hp_dma[2].awready = 1'b0;
axi_hp_dma[3].awready = 1'b0;
axi_hp_dma[1].arready = 1'b0;
axi_hp_dma[2].arready = 1'b0;
axi_hp_dma[3].arready = 1'b0;
axi_hp_dma[1].bvalid = 1'b0;
axi_hp_dma[2].bvalid = 1'b0;
axi_hp_dma[3].bvalid = 1'b0;
axi_hp_dma[1].rvalid = 1'b0;
axi_hp_dma[2].rvalid = 1'b0;
axi_hp_dma[3].rvalid = 1'b0;
end
// All other cases
end : axi_hp_directconnect else begin : axi_hp_interconnect
axi_interconnect_dma axi_interconnect_dma_i (
.m_axi_hp (axi_hp),
.s_axi_hp_dma (axi_hp_dma)
);
end : axi_hp_interconnect
//---------------------------------------------------------------------------
// 10 Gigabit Ethernet
//---------------------------------------------------------------------------
logic refclk; // 156 Mhz Ref 10 GbE
logic [0:0] qpll0_reset;
logic [3:0] qpll0_reset_i;
logic [0:0] qpll0_lock;
logic [0:0] qpll0_clk;
logic [0:0] qpll0_refclk;
logic [0:0] qpll1_reset;
logic [3:0] qpll1_reset_i;
logic [0:0] qpll1_lock;
logic [0:0] qpll1_clk;
logic [0:0] qpll1_refclk;
assign qpll0_reset[0] = qpll0_reset_i[0] || qpll0_reset_i[1] ||
qpll0_reset_i[2] || qpll0_reset_i[3];
assign qpll1_reset[0] = qpll1_reset_i[0] || qpll1_reset_i[1] ||
qpll1_reset_i[2] || qpll1_reset_i[3];
// The following logic is shared amongst potentially 4X10GBE interfaces
if (IS10GBE != 0) begin : xge_common
// Clocking signals for MGTs
IBUFDS_GTE4 ibufds_gte4_refclk (
.I (refclk_p),
.IB (refclk_n),
.CEB (1'b0),
.O (refclk),
.ODIV2 ()
);
xge_pcs_pma_common_wrapper xge_pcs_pma_common_wrapper_i (
.refclk (refclk),
.qpll0reset (qpll0_reset),
.qpll0lock (qpll0_lock),
.qpll0outclk (qpll0_clk),
.qpll0outrefclk (qpll0_refclk),
.qpll1reset (qpll1_reset),
.qpll1lock (qpll1_lock),
.qpll1outclk (qpll1_clk),
.qpll1outrefclk (qpll1_refclk)
);
end : xge_common
//---------------------------------------------------------------------------
// Generate QSFP Lanes
//---------------------------------------------------------------------------
logic [3:0] rx_rec_clk_out_i;
assign rx_rec_clk_out = rx_rec_clk_out_i[0];
generate
genvar lane;
begin : mgt_lanes
// Repeat logic for up to 4 QSFP lanes
for(lane = 0; lane < 4; lane++) begin : lane_loop
//---------------------------------------
// AXI-Lite to RegPort Bridge
//---------------------------------------
// Map to 0x4000 space
always_comb begin
`AXI4LITE_ASSIGN(m_axi_misc_v[lane],m_axi_misc[lane])
m_axi_misc_v[lane].araddr = 0;
m_axi_misc_v[lane].araddr[13:0] = m_axi_misc[lane].araddr[13:0];
m_axi_misc_v[lane].awaddr = 0;
m_axi_misc_v[lane].awaddr[13:0] = m_axi_misc[lane].awaddr[13:0];
end
// AXI4-Lite to RegPort (PS to PL Register Access)
// NOTE: We always have a register interface even if the block is
// unused, so that the driver can query the status.
typedef logic [REG_AWIDTH_MISC-1:0] reg_addr_t;
typedef logic [REG_DWIDTH-1:0] reg_data_t;
logic reg_wr_req;
reg_addr_t reg_wr_addr;
reg_data_t reg_wr_data;
logic reg_rd_req;
reg_addr_t reg_rd_addr;
logic reg_rd_resp, reg_rd_resp_io, reg_rd_resp_eth_if;
reg_data_t reg_rd_data, reg_rd_data_io, reg_rd_data_eth_if;
axil_regport_master #(
.DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
.AWIDTH (REG_AWIDTH_MISC), // Width of the address bus
.WRBASE (0), // Write address base
.RDBASE (0), // Read address base
.TIMEOUT (10) // log2(timeout). Read will timeout after (2^TIMEOUT - 1) cycles
) axil_regport_master_i (
// Clock and reset
.s_axi_aclk (m_axi_misc_v[lane].clk),
.s_axi_aresetn (!m_axi_misc_v[lane].rst),
`AXI4LITE_PORT_ASSIGN_NR(s_axi,m_axi_misc_v[lane])
// Register port: Write port (domain: reg_clk)
.reg_clk (bus_clk),
.reg_wr_req (reg_wr_req),
.reg_wr_addr (reg_wr_addr),
.reg_wr_data (reg_wr_data),
.reg_wr_keep (/*unused*/),
// Register port: Read port (domain: reg_clk)
.reg_rd_req (reg_rd_req),
.reg_rd_addr (reg_rd_addr),
.reg_rd_resp (reg_rd_resp),
.reg_rd_data (reg_rd_data)
);
// Regport Mux for response
regport_resp_mux #(
.WIDTH (REG_DWIDTH),
.NUM_SLAVES (2)
) regport_resp_mux_i (
.clk(bus_clk), .reset(bus_rst),
.sla_rd_resp({reg_rd_resp_eth_if, reg_rd_resp_io}),
.sla_rd_data({reg_rd_data_eth_if, reg_rd_data_io}),
.mst_rd_resp(reg_rd_resp), .mst_rd_data(reg_rd_data)
);
//---------------------------------------
// MGT IO Core
//---------------------------------------
localparam MGT_W = (IS100GBE) ? 512 : 64;
localparam MGT_USER_W = $clog2(MGT_W/8)+1;
// The Clocking for the MGT interfaces comes from the MGT Wrapper
// depending on the bus it may change.
logic mgt_rst, mgt_clk;
AxiStreamIf #(.DATA_WIDTH(MGT_W),.USER_WIDTH(MGT_USER_W))
mgt_tx(mgt_clk, mgt_rst);
AxiStreamIf #(.DATA_WIDTH(MGT_W),.USER_WIDTH(MGT_USER_W),.TKEEP(0))
mgt_rx(mgt_clk, mgt_rst);
logic mgt_pause_req;
logic [3:0] tx_p_lane;
logic [3:0] tx_n_lane;
if (IS10GBE[lane]) begin
// Single lane case:
assign tx_p[lane] = tx_p_lane[lane];
assign tx_n[lane] = tx_n_lane[lane];
end else if (IS100GBE[lane] || ISAURORA[lane]) begin
// Multi lane case:
assign tx_p = tx_p_lane;
assign tx_n = tx_n_lane;
end
x4xx_mgt_io_core #(
.PROTOCOL (PROTOCOL[lane]),
.REG_BASE (REG_BASE_SFP_IO),
.REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
.REG_AWIDTH (REG_AWIDTH_MISC), // Width of the address bus
.PORTNUM (PORTNUM),
.LANENUM (lane)
) x4xx_mgt_io_core_i (
// Must reset all channels on quad when QSFP GTX core is reset
.areset (areset),
.mgt_rst (mgt_rst),
.mgt_clk (mgt_clk),
.clk100 (clk100),
.bus_rst (bus_rst),
.bus_clk (bus_clk),
.refclk_p (refclk_p),
.refclk_n (refclk_n),
.tx_p (tx_p_lane),
.tx_n (tx_n_lane),
.rx_p (rx_p),
.rx_n (rx_n),
// Common signals (for single lane instances)
.qpll0_reset (qpll0_reset_i[lane]),
.qpll0_lock (qpll0_lock),
.qpll0_clk (qpll0_clk),
.qpll0_refclk (qpll0_refclk),
.qpll1_reset (qpll1_reset_i[lane]),
.qpll1_lock (qpll1_lock),
.qpll1_clk (qpll1_clk),
.qpll1_refclk (qpll1_refclk),
// RegPort
.reg_wr_req (reg_wr_req),
.reg_wr_addr (reg_wr_addr),
.reg_wr_data (reg_wr_data),
.reg_rd_req (reg_rd_req),
.reg_rd_addr (reg_rd_addr),
.reg_rd_resp (reg_rd_resp_io),
.reg_rd_data (reg_rd_data_io),
// AxiLite
.m_axi_mac (m_axi_mac[lane]),
// Pause
.mgt_pause_req (mgt_pause_req),
// Data
.mgt_tx (mgt_tx),
.mgt_rx (mgt_rx),
// Misc.
.rx_rec_clk_out (rx_rec_clk_out_i[lane]),
.port_info (port_info[lane]),
.link_up (link_up[lane]),
.activity (activity[lane])
);
if (IS100GBE[lane] || IS10GBE[lane]) begin : eth_port
//---------------------------------------
// Ethernet IPv4 Interface for CHDR
//---------------------------------------
// Option to use a bigger FIFO for 100GBe.
// This is address width so +1 doubles the size +2 quadruples it.
localparam CHDR_FIFO_SIZE = (IS100GBE[lane]) ? BYTE_MTU+2 : BYTE_MTU;
AxiStreamIf #(.DATA_WIDTH(CPU_W), .USER_WIDTH(CPU_USER_W), .TUSER(0))
c2e (s_axi.clk, s_axi.rst);
AxiStreamIf #(.DATA_WIDTH(CPU_W), .USER_WIDTH(CPU_USER_W), .TUSER(0))
e2c (s_axi.clk, s_axi.rst);
localparam PAUSE_EN = (IS100GBE[lane]) ? 1 : 0;
// Ethernet interface
// (1) routes the packet to CHDR/CPU
// (2) implements a wrap back (eth_tx/eth_rx)
eth_ipv4_interface #(
.PROTOVER (RFNOC_PROTOVER),
.CPU_FIFO_SIZE (BYTE_MTU),
.CHDR_FIFO_SIZE (CHDR_FIFO_SIZE),
.NODE_INST (NODE_INST+lane),
.BASE (REG_BASE_ETH_SWITCH),
.PREAMBLE_BYTES (0),
.ADD_SOF (0),
.SYNC (0), // c2e/e2c don't use the same clock as eth_tx/eth_rx
.PAUSE_EN (PAUSE_EN),
.ENET_W (MGT_W),
.CPU_W (CPU_W),
.CHDR_W (CHDR_W),
.NET_CHDR_W (NET_CHDR_W)
) eth_ipv4_interface_i (
.bus_clk (bus_clk),
.bus_rst (bus_rst),
.device_id (device_id),
.reg_wr_req (reg_wr_req),
.reg_wr_addr (reg_wr_addr),
.reg_wr_data (reg_wr_data),
.reg_rd_req (reg_rd_req),
.reg_rd_addr (reg_rd_addr),
.reg_rd_resp (reg_rd_resp_eth_if),
.reg_rd_data (reg_rd_data_eth_if),
.eth_pause_req (mgt_pause_req),
.eth_tx (mgt_tx),
.eth_rx (mgt_rx),
.e2v (e2v[lane]),
.v2e (v2e[lane]),
.e2c (e2c),
.c2e (c2e),
.my_udp_chdr_port (/* unused */),
.my_ip (/* unused */),
.my_mac (/* unused */)
);
axi_eth_dma axi_eth_dma_i (
.c2e (c2e),
.e2c (e2c),
.s_axi_eth_dma (m_axi_dma[lane]),
.axi_hp (axi_hp_dma[lane]),
.eth_tx_irq (eth_tx_irq[lane]),
.eth_rx_irq (eth_rx_irq[lane])
);
end : eth_port else begin : not_eth
//---------------------------------------
// Terminate DMA for Unused Ethernet
//---------------------------------------
// Set unused ETH_DMA ports to default value
always_comb begin
m_axi_dma[lane].drive_read_resp(.resp(SLVERR),.data(0));
m_axi_dma[lane].drive_write_resp(.resp(SLVERR));
m_axi_dma[lane].arready = 1'b1;
m_axi_dma[lane].awready = 1'b1;
m_axi_dma[lane].wready = 1'b1;
axi_hp_dma[lane].drive_read_idle();
axi_hp_dma[lane].drive_aw_idle();
axi_hp_dma[lane].drive_w_idle();
axi_hp_dma[lane].bready = 1'b0;
axi_hp_dma[lane].rready = 1'b0;
mgt_pause_req = 0'b0;
eth_rx_irq[lane] = 1'b0;
eth_tx_irq[lane] = 1'b0;
reg_rd_resp_eth_if = 1'b0;
reg_rd_data_eth_if = 'h0;
end
if (ISAURORA[lane]) begin : aurora_port
//---------------------------------------
// Aurora
//---------------------------------------
Aurora_not_yet_supported();
// if MGT_W and CHDR_W mismatch figure out what to do
always_comb begin
e2v[lane].tdata = mgt_rx.tdata;
e2v[lane].tuser = 'b0;
e2v[lane].tkeep = 'b1;
e2v[lane].tlast = mgt_rx.tlast;
e2v[lane].tvalid = mgt_rx.tvalid;
mgt_rx.tready = e2v[lane].tready;
mgt_tx.tdata = v2e[lane].tdata;
mgt_tx.tuser = 'b0;
mgt_tx.tkeep = 'b1;
mgt_tx.tlast = v2e[lane].tlast;
mgt_tx.tvalid = v2e[lane].tvalid;
v2e[lane].tready = mgt_tx.tready;
end
end else begin : inactive_port
//---------------------------------------
// Disabled Port
//---------------------------------------
always_comb begin
e2v[lane].tdata = 'b0;
e2v[lane].tuser = 'b0;
e2v[lane].tkeep = 'b1;
e2v[lane].tlast = 1'b0;
e2v[lane].tvalid = 1'b0;
mgt_rx.tready = 1'b1;
mgt_tx.tdata = 'b0;
mgt_tx.tuser = 'b0;
mgt_tx.tkeep = 'b1;
mgt_tx.tlast = 1'b0;
mgt_tx.tvalid = 1'b0;
v2e[lane].tready = 1'b1;
end
end : inactive_port
end : not_eth
end : lane_loop
end : mgt_lanes
endgenerate
endmodule
-333
View File
@@ -1,333 +0,0 @@
//
// Copyright 2021 Ettus Research, A National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: x4xx_qsfp_wrapper_temp
//
// Description:
//
// Translation layer between Verilog and SystemVerilog for x4xx_qsfp_wrapper.
//
// Parameters:
//
// PROTOCOL : Indicates the protocol to use for each of the 4 QSFP
// lanes. See x4xx_mgt_types.vh for possible values.
// CHDR_W : CHDR width used by RFNoC on the FPGA
// NET_CHDR_W : CHDR width used over the network connection
// BYTE_MTU : Transport MTU in bytes
// PORTNUM : Port number to distinguish multiple QSFP ports
// NODE_INST : RFNoC transport adapter node instance for the first port
// RFNOC_PROTOVER : RFNoC protocol version for IPv4 interface
//
`include "./x4xx_mgt_types.vh"
module x4xx_qsfp_wrapper_temp #(
parameter PROTOCOL0 = `MGT_Disabled,
parameter PROTOCOL1 = `MGT_Disabled,
parameter PROTOCOL2 = `MGT_Disabled,
parameter PROTOCOL3 = `MGT_Disabled,
parameter CHDR_W = 64,
parameter NET_CHDR_W = CHDR_W,
parameter BYTE_MTU = $clog2(8*1024),
parameter [ 7:0] PORTNUM = 8'd0,
parameter NODE_INST = 0,
parameter [15:0] RFNOC_PROTOVER = {8'd1, 8'd0}
) (
// Resets
input logic areset,
input logic bus_rst,
input logic clk40_rst,
// Clocks
input logic refclk_p,
input logic refclk_n,
input logic clk100,
input logic clk40,
input logic bus_clk,
// AXI-Lite
input logic [39:0] s_axi_awaddr,
input logic s_axi_awvalid,
output logic s_axi_awready,
input logic [31:0] s_axi_wdata,
input logic [ 3:0] s_axi_wstrb,
input logic s_axi_wvalid,
output logic s_axi_wready,
output logic [ 1:0] s_axi_bresp,
output logic s_axi_bvalid,
input logic s_axi_bready,
input logic [39:0] s_axi_araddr,
input logic s_axi_arvalid,
output logic s_axi_arready,
output logic [31:0] s_axi_rdata,
output logic [ 1:0] s_axi_rresp,
output logic s_axi_rvalid,
input logic s_axi_rready,
// MGT high-speed IO
output logic [3:0] tx_p,
output logic [3:0] tx_n,
input logic [3:0] rx_p,
input logic [3:0] rx_n,
// CHDR router interface
output logic [4*CHDR_W-1:0] e2v_tdata,
output logic [ 3:0] e2v_tlast,
output logic [ 3:0] e2v_tvalid,
input logic [ 3:0] e2v_tready,
input logic [4*CHDR_W-1:0] v2e_tdata,
input logic [ 3:0] v2e_tlast,
input logic [ 3:0] v2e_tvalid,
output logic [ 3:0] v2e_tready,
// Ethernet DMA AXI to CPU memory
output logic [ 48:0] axi_hp_araddr,
output logic [ 1:0] axi_hp_arburst,
output logic [ 3:0] axi_hp_arcache,
output logic [ 7:0] axi_hp_arlen,
output logic [ 0:0] axi_hp_arlock,
output logic [ 2:0] axi_hp_arprot,
output logic [ 3:0] axi_hp_arqos,
input logic axi_hp_arready,
output logic [ 2:0] axi_hp_arsize,
output logic axi_hp_arvalid,
output logic [ 48:0] axi_hp_awaddr,
output logic [ 1:0] axi_hp_awburst,
output logic [ 3:0] axi_hp_awcache,
output logic [ 7:0] axi_hp_awlen,
output logic [ 0:0] axi_hp_awlock,
output logic [ 2:0] axi_hp_awprot,
output logic [ 3:0] axi_hp_awqos,
input logic axi_hp_awready,
output logic [ 2:0] axi_hp_awsize,
output logic axi_hp_awvalid,
output logic axi_hp_bready,
input logic [ 1:0] axi_hp_bresp,
input logic axi_hp_bvalid,
input logic [127:0] axi_hp_rdata,
input logic axi_hp_rlast,
output logic axi_hp_rready,
input logic [ 1:0] axi_hp_rresp,
input logic axi_hp_rvalid,
output logic [127:0] axi_hp_wdata,
output logic axi_hp_wlast,
input logic axi_hp_wready,
output logic [ 15:0] axi_hp_wstrb,
output logic axi_hp_wvalid,
// Ethernet DMA IRQs
output logic [3:0] eth_rx_irq,
output logic [3:0] eth_tx_irq,
// Misc.
output logic rx_rec_clk_out,
input logic [15:0] device_id,
output logic [31:0] port_info_0,
output logic [31:0] port_info_1,
output logic [31:0] port_info_2,
output logic [31:0] port_info_3,
output logic [3:0] link_up,
output logic [3:0] activity
);
import PkgAxiLite::*;
`include "../../lib/axi4lite_sv/axi_lite.vh"
`include "../../lib/axi4s_sv/axi4s.vh"
//---------------------------------------------------------------------------
// AXI Interfaces
//---------------------------------------------------------------------------
localparam CHDR_USER_W = $clog2(CHDR_W/8);
// AXI-Stream for RFNoC CHDR
AxiStreamIf #(.DATA_WIDTH(CHDR_W), .USER_WIDTH(CHDR_USER_W),
.TKEEP(0), .TUSER(0))
v2e[4] (bus_clk, bus_rst);
AxiStreamIf #(.DATA_WIDTH(CHDR_W), .USER_WIDTH(CHDR_USER_W),
.TKEEP(0), .TUSER(0))
e2v[4] (bus_clk, bus_rst);
// AXI-Lite register interface
AxiLiteIf #(.DATA_WIDTH(32), .ADDR_WIDTH(40))
s_axi (clk40, clk40_rst);
// AXI (Full) for DMA back to CPU memory
AxiIf #(.DATA_WIDTH(128), .ADDR_WIDTH(49))
axi_hp (clk40, clk40_rst);
logic [3:0][31:0] port_info;
//---------------------------------------------------------------------------
// Translate Signals to Interfaces
//---------------------------------------------------------------------------
always_comb begin
port_info_0 = port_info[0];
port_info_1 = port_info[1];
port_info_2 = port_info[2];
port_info_3 = port_info[3];
//---------------------------------
// s_axi
//---------------------------------
// Write channel
s_axi.awaddr[39:18] = 0;
s_axi.awaddr[17:0] = s_axi_awaddr[17:0]; // 256 KiB window
s_axi.awvalid = s_axi_awvalid;
s_axi_awready = s_axi.awready;
s_axi.wdata = s_axi_wdata[31:0];
s_axi.wstrb = s_axi_wstrb;
s_axi.wvalid = s_axi_wvalid;
s_axi_wready = s_axi.wready;
s_axi_bresp = s_axi.bresp[1:0];
s_axi_bvalid = s_axi.bvalid;
s_axi.bready = s_axi_bready;
// Read channel
s_axi.araddr[39:18] = 0;
s_axi.araddr[17:0] = s_axi_araddr[17:0]; // 256 KiB window
s_axi.arvalid = s_axi_arvalid;
s_axi_arready = s_axi.arready;
s_axi_rdata[31:0] = s_axi.rdata;
s_axi_rresp = s_axi.rresp[1:0];
s_axi_rvalid = s_axi.rvalid;
s_axi.rready = s_axi_rready;
//---------------------------------
// axi_hp
//---------------------------------
// Write channel
axi_hp_awaddr = axi_hp.awaddr;
axi_hp_awburst = axi_hp.awburst;
axi_hp_awcache = axi_hp.awcache;
axi_hp_awlen = axi_hp.awlen;
axi_hp_awsize = axi_hp.awsize;
axi_hp_awlock = axi_hp.awlock;
axi_hp_awprot = axi_hp.awprot;
axi_hp_awqos = axi_hp.awqos;
axi_hp_awvalid = axi_hp.awvalid;
axi_hp.awready = axi_hp_awready;
axi_hp_wdata = axi_hp.wdata;
axi_hp_wstrb = axi_hp.wstrb;
axi_hp_wlast = axi_hp.wlast;
axi_hp_wvalid = axi_hp.wvalid;
axi_hp.wready = axi_hp_wready;
axi_hp.bresp[1:0] = axi_hp_bresp;
axi_hp.bvalid = axi_hp_bvalid;
axi_hp_bready = axi_hp.bready;
// Read channel
axi_hp_araddr = axi_hp.araddr;
axi_hp_arburst = axi_hp.arburst;
axi_hp_arcache = axi_hp.arcache;
axi_hp_arlen = axi_hp.arlen;
axi_hp_arsize = axi_hp.arsize;
axi_hp_arlock = axi_hp.arlock;
axi_hp_arprot = axi_hp.arprot;
axi_hp_arqos = axi_hp.arqos;
axi_hp_arvalid = axi_hp.arvalid;
axi_hp.arready = axi_hp_arready;
axi_hp.rdata = axi_hp_rdata;
axi_hp.rresp[1:0] = axi_hp_rresp;
axi_hp.rlast = axi_hp_rlast;
axi_hp.rvalid = axi_hp_rvalid;
axi_hp_rready = axi_hp.rready;
//---------------------------------
// CHDR Links
//---------------------------------
e2v_tdata[1*CHDR_W-1:0*CHDR_W] = e2v[0].tdata;
e2v_tlast[0] = e2v[0].tlast;
e2v_tvalid[0] = e2v[0].tvalid;
e2v[0].tready = e2v_tready[0];
e2v_tdata[2*CHDR_W-1:1*CHDR_W] = e2v[1].tdata;
e2v_tlast[1] = e2v[1].tlast;
e2v_tvalid[1] = e2v[1].tvalid;
e2v[1].tready = e2v_tready[1];
e2v_tdata[3*CHDR_W-1:2*CHDR_W] = e2v[2].tdata;
e2v_tlast[2] = e2v[2].tlast;
e2v_tvalid[2] = e2v[2].tvalid;
e2v[2].tready = e2v_tready[2];
e2v_tdata[4*CHDR_W-1:3*CHDR_W] = e2v[3].tdata;
e2v_tlast[3] = e2v[3].tlast;
e2v_tvalid[3] = e2v[3].tvalid;
e2v[3].tready = e2v_tready[3];
v2e[0].tdata = v2e_tdata[1*CHDR_W-1:0*CHDR_W];
v2e[0].tlast = v2e_tlast[0];
v2e[0].tvalid = v2e_tvalid[0];
v2e_tready[0] = v2e[0].tready;
v2e[1].tdata = v2e_tdata[2*CHDR_W-1:1*CHDR_W];
v2e[1].tlast = v2e_tlast[1];
v2e[1].tvalid = v2e_tvalid[1];
v2e_tready[1] = v2e[1].tready;
v2e[2].tdata = v2e_tdata[3*CHDR_W-1:2*CHDR_W];
v2e[2].tlast = v2e_tlast[2];
v2e[2].tvalid = v2e_tvalid[2];
v2e_tready[2] = v2e[2].tready;
v2e[3].tdata = v2e_tdata[4*CHDR_W-1:3*CHDR_W];
v2e[3].tlast = v2e_tlast[3];
v2e[3].tvalid = v2e_tvalid[3];
v2e_tready[3] = v2e[3].tready;
end
x4xx_qsfp_wrapper #(
.PROTOCOL ({ PROTOCOL3, PROTOCOL2, PROTOCOL1, PROTOCOL0 }),
.CHDR_W (CHDR_W),
.NET_CHDR_W (NET_CHDR_W),
.BYTE_MTU (BYTE_MTU),
.PORTNUM (PORTNUM),
.NODE_INST (NODE_INST),
.RFNOC_PROTOVER (RFNOC_PROTOVER)
) x4xx_qsfp_wrapper_i (
.areset (areset),
.refclk_p (refclk_p),
.refclk_n (refclk_n),
.bus_rst (bus_rst),
.clk40_rst (clk40_rst),
.clk100 (clk100),
.bus_clk (bus_clk),
.s_axi (s_axi),
.tx_p (tx_p),
.tx_n (tx_n),
.rx_p (rx_p),
.rx_n (rx_n),
.e2v (e2v),
.v2e (v2e),
.axi_hp (axi_hp),
.eth_tx_irq (eth_tx_irq),
.eth_rx_irq (eth_rx_irq),
.device_id (device_id),
.rx_rec_clk_out (rx_rec_clk_out),
.port_info (port_info),
.link_up (link_up),
.activity (activity)
);
endmodule