fpga: e320: Support advanced transport adapter

- Fix NODE_INST
- Fix RFNOC_PROTOVER
- Add option to use SystemVerilog transport adapter for raw UDP


Original-commit: 0114e108af63d9ac785649c8099a042299624943
This commit is contained in:
Wade Fife
2022-08-29 17:01:45 -05:00
committed by skooNI
parent a270cb29d6
commit 5f4d53eacb
5 changed files with 461 additions and 527 deletions
+6 -2
View File
@@ -33,6 +33,9 @@ include $(LIB_DIR)/xge_interface/Makefile.srcs
include $(LIB_DIR)/dsp/Makefile.srcs
include $(LIB_DIR)/io_cap_gen/Makefile.srcs
include $(LIB_DIR)/rfnoc/Makefile.srcs
include $(LIB_DIR)/axi4s_sv/Makefile.srcs
include $(LIB_DIR)/rfnoc/xport_sv/Makefile.srcs
# For sake of convenience, we include the Makefile.srcs for DRAM FIFO, DDC, and
# DUC, and of course the radio. Any other block needs to use the
# RFNOC_OOT_MAKEFILE_SRCS variable (see below).
@@ -56,8 +59,8 @@ TOP_SRCS = \
e320.v \
e320_core.v \
e320_clocking.v \
n3xx_sfp_wrapper.v \
n3xx_mgt_io_core.v \
e320_sfp_wrapper.v \
e320_mgt_io_core.v \
$(IMAGE_CORE)
MB_XDC = \
@@ -117,6 +120,7 @@ $(RFNOC_FRAMEWORK_SRCS) \
$(RFNOC_BLOCK_AXI_RAM_FIFO_SRCS) \
$(RFNOC_BLOCK_DUC_SRCS) $(RFNOC_BLOCK_DDC_SRCS) \
$(RFNOC_BLOCK_RADIO_SRCS) \
$(AXI4S_SV_SRCS) $(RFNOC_XPORT_SV_SRCS) \
$(abspath $(MB_XDC))
EDGE_TBL_DEF="RFNOC_EDGE_TBL_FILE=$(call RESOLVE_PATH,$(EDGE_FILE))"
+36 -40
View File
@@ -1075,44 +1075,25 @@ module e320 (
//
/////////////////////////////////////////////////////////////////////
n3xx_sfp_wrapper #(
e320_sfp_wrapper #(
.PROTOCOL(PROTOCOL),
.MDIO_EN(MDIO_EN),
.MDIO_PHYADDR(MDIO_PHYADDR),
.DWIDTH(REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
.AWIDTH(REG_AWIDTH), // Width of the address bus
.PORTNUM(SFP_PORTNUM)
.PORTNUM(SFP_PORTNUM),
.MDIO_EN(MDIO_EN),
.MDIO_PHYADDR(MDIO_PHYADDR),
.RFNOC_PROTOVER(RFNOC_PROTOVER),
.NODE_INST(0)
) sfp_wrapper_i (
// Resets
.areset(bus_rst),
.bus_rst(bus_rst),
// Clocks
.gt_refclk(sfp_gt_refclk),
.gb_refclk(sfp_gb_refclk),
.misc_clk(sfp_misc_clk),
.bus_rst(bus_rst),
.bus_clk(bus_clk),
.user_clk(),
.sync_clk(),
// GT_COMMON
.qpllreset(),
.qplllock(1'b0),
.qplloutclk(1'b0),
.qplloutrefclk(1'b0),
.qpllrefclklost(),
.mmcm_locked(1'b0),
.gt_pll_lock(),
.txp(SFP1_TX_P),
.txn(SFP1_TX_N),
.rxp(SFP1_RX_P),
.rxn(SFP1_RX_N),
.sfpp_rxlos(SFP1_RXLOS),
.sfpp_tx_fault(SFP1_TXFAULT),
.sfpp_tx_disable(SFP1_TXDISABLE),
// Clock and reset
// AXI4-Lite: Clock and reset
.s_axi_aclk(reg_clk),
.s_axi_aresetn(reg_rstn),
// AXI4-Lite: Write address port (domain: s_axi_aclk)
@@ -1137,37 +1118,50 @@ module e320 (
.s_axi_rresp(m_axi_net_rresp),
.s_axi_rvalid(m_axi_net_rvalid),
.s_axi_rready(m_axi_net_rready),
// Ethernet to Vita
// SFP high-speed IO
.txp(SFP1_TX_P),
.txn(SFP1_TX_N),
.rxp(SFP1_RX_P),
.rxn(SFP1_RX_N),
// SFP low-speed IO
.sfpp_present_n(1'b0),
.sfpp_rxlos(SFP1_RXLOS),
.sfpp_tx_fault(SFP1_TXFAULT),
.sfpp_tx_disable(SFP1_TXDISABLE),
// GT Common
.qpllrefclklost(),
.qplllock(1'b0),
.qplloutclk(1'b0),
.qplloutrefclk(1'b0),
.qpllreset(),
// Aurora MMCM
.mmcm_locked(1'b0),
.gt_pll_lock(),
// Ethernet to RFNoC
.e2v_tdata(e2v_tdata),
.e2v_tlast(e2v_tlast),
.e2v_tvalid(e2v_tvalid),
.e2v_tready(e2v_tready),
// Vita to Ethernet
// RFNoC to Ethernet
.v2e_tdata(v2e_tdata),
.v2e_tlast(v2e_tlast),
.v2e_tvalid(v2e_tvalid),
.v2e_tready(v2e_tready),
// Ethernet to CPU
.e2c_tdata(arm_eth_rx_tdata_b),
.e2c_tkeep(arm_eth_rx_tkeep_b),
.e2c_tlast(arm_eth_rx_tlast_b),
.e2c_tvalid(arm_eth_rx_tvalid_b),
.e2c_tready(arm_eth_rx_tready_b),
// CPU to Ethernet
.c2e_tdata(arm_eth_tx_tdata_b),
.c2e_tkeep(arm_eth_tx_tkeep_b),
.c2e_tlast(arm_eth_tx_tlast_b),
.c2e_tvalid(arm_eth_tx_tvalid_b),
.c2e_tready(arm_eth_tx_tready_b),
// Misc
.port_info(sfp_port_info),
.device_id(device_id),
// LED
.link_up(sfp_link_up),
.activity(LED_ACT1)
@@ -1325,9 +1319,11 @@ module e320 (
//
//////////////////////////////////////////////////////////////////////
eth_internal #(
.DWIDTH(REG_DWIDTH),
.AWIDTH(REG_AWIDTH),
.PORTNUM(8'd1)
.DWIDTH (REG_DWIDTH),
.AWIDTH (REG_AWIDTH),
.PORTNUM (8'd1),
.RFNOC_PROTOVER (RFNOC_PROTOVER),
.NODE_INST (1)
) eth_internal_i (
// Resets
.bus_rst (bus_rst),
@@ -11,7 +11,7 @@
//
//////////////////////////////////////////////////////////////////////
module n3xx_mgt_io_core #(
module e320_mgt_io_core #(
parameter PROTOCOL = "10GbE", // Must be {10GbE, 1GbE, Aurora, Disabled}
parameter [13:0] REG_BASE = 14'h0,
parameter REG_DWIDTH = 32,
+418
View File
@@ -0,0 +1,418 @@
//
// Copyright 2022 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: e320_sfp_wrapper
//
// Description:
//
// Wrapper for SFP port, including support for Aurora, 10 GbE, and 1 GbE.
//
// Parameters:
//
// PROTOCOL : Must be "10GbE", "1GbE", "Aurora", or "Disabled".
// REG_DWIDTH : Data width of the AXI-Lite interface and RegPort
// REG_AWIDTH : Address width of the AXI-Lite interface and RegPort
// PORTNUM : Port number
// MDIO_EN : Enables internal MDIO master
// MDIO_PHYADDR : Address to use for the MDIO
// RFNOC_PROTOVER : RFNoC protocol version to be reported by transport
// adapters.
// NODE_INST : RFNoC transport adapter node instance for this port
// EN_RX_KV_MAP_CFG : Enable KV-map configuration port on transport adapter
// EN_RX_RAW_PYLD : Enable raw UDP support on transport adapter
//
`default_nettype none
module e320_sfp_wrapper #(
parameter PROTOCOL = "10GbE",
parameter DWIDTH = 32,
parameter AWIDTH = 14,
parameter [7:0] PORTNUM = 8'd0,
parameter MDIO_EN = 0,
parameter [4:0] MDIO_PHYADDR = 5'd0,
parameter [15:0] RFNOC_PROTOVER = {8'd1, 8'd0},
parameter NODE_INST = 0,
parameter EN_RX_KV_MAP_CFG = 1,
parameter EN_RX_RAW_PYLD = 1
) (
// Resets
input wire areset,
input wire bus_rst,
// Clocks
input wire gt_refclk,
input wire gb_refclk,
input wire misc_clk,
input wire bus_clk,
// AXI-Lite
input wire s_axi_aclk,
input wire s_axi_aresetn,
input wire [ AWIDTH-1:0] s_axi_awaddr,
input wire s_axi_awvalid,
output wire s_axi_awready,
input wire [ DWIDTH-1:0] s_axi_wdata,
input wire [DWIDTH/8-1:0] s_axi_wstrb,
input wire s_axi_wvalid,
output wire s_axi_wready,
output wire [ 1:0] s_axi_bresp,
output wire s_axi_bvalid,
input wire s_axi_bready,
input wire [ AWIDTH-1:0] s_axi_araddr,
input wire s_axi_arvalid,
output wire s_axi_arready,
output wire [ DWIDTH-1:0] s_axi_rdata,
output wire [ 1:0] s_axi_rresp,
output wire s_axi_rvalid,
input wire s_axi_rready,
// SFP high-speed IO
output wire txp,
output wire txn,
input wire rxp,
input wire rxn,
// SFP low-speed IO
input wire sfpp_present_n,
input wire sfpp_rxlos,
input wire sfpp_tx_fault,
output wire sfpp_tx_disable,
// GT Common
input wire qpllrefclklost,
input wire qplllock,
input wire qplloutclk,
input wire qplloutrefclk,
output wire qpllreset,
// Aurora MMCM
input wire mmcm_locked,
output wire gt_pll_lock,
output wire gt_tx_out_clk_unbuf,
// Ethernet to RFNoC
output wire [63:0] e2v_tdata,
output wire e2v_tlast,
output wire e2v_tvalid,
input wire e2v_tready,
// RFNoC to Ethernet
input wire [63:0] v2e_tdata,
input wire v2e_tlast,
input wire v2e_tvalid,
output wire v2e_tready,
// Ethernet to CPU
output wire [63:0] e2c_tdata,
output wire [ 7:0] e2c_tkeep,
output wire e2c_tlast,
output wire e2c_tvalid,
input wire e2c_tready,
// CPU to Ethernet
input wire [63:0] c2e_tdata,
input wire [ 7:0] c2e_tkeep,
input wire c2e_tlast,
input wire c2e_tvalid,
output wire c2e_tready,
// Misc
output wire [31:0] port_info,
input wire [15:0] device_id,
output wire link_up,
output wire activity
);
localparam REG_BASE_SFP_IO = 14'h0;
localparam REG_BASE_ETH_SWITCH = 14'h1000;
// AXI4-Lite to RegPort (PS to PL Register Access)
wire reg_wr_req;
wire [AWIDTH-1:0] reg_wr_addr;
wire [DWIDTH-1:0] reg_wr_data;
wire reg_rd_req;
wire [AWIDTH-1:0] reg_rd_addr;
wire reg_rd_resp, reg_rd_resp_io, reg_rd_resp_eth_if;
wire [DWIDTH-1:0] reg_rd_data, reg_rd_data_io, reg_rd_data_eth_if;
axil_regport_master #(
.DWIDTH (DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
.AWIDTH (AWIDTH), // 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
) sfp_reg_mst_i (
// Clock and reset
.s_axi_aclk (s_axi_aclk),
.s_axi_aresetn (s_axi_aresetn),
// AXI4-Lite: Write address port (domain: s_axi_aclk)
.s_axi_awaddr (s_axi_awaddr),
.s_axi_awvalid (s_axi_awvalid),
.s_axi_awready (s_axi_awready),
// AXI4-Lite: Write data port (domain: s_axi_aclk)
.s_axi_wdata (s_axi_wdata),
.s_axi_wstrb (s_axi_wstrb),
.s_axi_wvalid (s_axi_wvalid),
.s_axi_wready (s_axi_wready),
// AXI4-Lite: Write response port (domain: s_axi_aclk)
.s_axi_bresp (s_axi_bresp),
.s_axi_bvalid (s_axi_bvalid),
.s_axi_bready (s_axi_bready),
// AXI4-Lite: Read address port (domain: s_axi_aclk)
.s_axi_araddr (s_axi_araddr),
.s_axi_arvalid (s_axi_arvalid),
.s_axi_arready (s_axi_arready),
// AXI4-Lite: Read data port (domain: s_axi_aclk)
.s_axi_rdata (s_axi_rdata),
.s_axi_rresp (s_axi_rresp),
.s_axi_rvalid (s_axi_rvalid),
.s_axi_rready (s_axi_rready),
// 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),
// 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 (DWIDTH),
.NUM_SLAVES (2)
) reg_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)
);
wire [63:0] sfpo_tdata, sfpi_tdata;
wire [3:0] sfpo_tuser, sfpi_tuser;
wire sfpo_tlast, sfpi_tlast, sfpo_tvalid, sfpi_tvalid, sfpo_tready, sfpi_tready;
e320_mgt_io_core #(
.PROTOCOL (PROTOCOL),
.REG_BASE (REG_BASE_SFP_IO),
.REG_DWIDTH (DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
.REG_AWIDTH (AWIDTH), // Width of the address bus
.MDIO_EN (MDIO_EN),
.MDIO_PHYADDR (MDIO_PHYADDR),
.PORTNUM (PORTNUM)
) mgt_io_i (
.areset (areset),
.gt_refclk (gt_refclk),
.gb_refclk (gb_refclk),
.misc_clk (misc_clk),
.bus_rst (bus_rst),
.bus_clk (bus_clk),
.txp (txp),
.txn (txn),
.rxp (rxp),
.rxn (rxn),
.sfpp_rxlos (sfpp_rxlos),
.sfpp_tx_fault (sfpp_tx_fault),
.sfpp_tx_disable(sfpp_tx_disable),
// 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),
// RFNoC to Ethernet
.s_axis_tdata (sfpi_tdata),
.s_axis_tuser (sfpi_tuser),
.s_axis_tlast (sfpi_tlast),
.s_axis_tvalid (sfpi_tvalid),
.s_axis_tready (sfpi_tready),
// Ethernet to RFNoC
.m_axis_tdata (sfpo_tdata),
.m_axis_tuser (sfpo_tuser),
.m_axis_tlast (sfpo_tlast),
.m_axis_tvalid (sfpo_tvalid),
.m_axis_tready (sfpo_tready),
.port_info (port_info),
.link_up (link_up),
.activity (activity)
);
generate
// Tie off the Ethernet switch for these protocols that do not use it.
if (PROTOCOL == "Aurora" || PROTOCOL == "Disabled") begin : gen_no_eth
//set unused wires to default value
assign e2c_tdata = 64'h0;
assign e2c_tkeep = 8'h0;
assign e2c_tlast = 1'b0;
assign e2c_tvalid = 1'b0;
assign c2e_tready = 1'b1;
assign reg_rd_resp_eth_if = 1'b0;
assign reg_rd_data_eth_if = 'h0;
end else begin : gen_eth
wire [3:0] e2c_tuser;
wire [3:0] c2e_tuser;
// In AXI Stream, tkeep is the byte qualifier that indicates
// whether the content of the associated byte
// of TDATA is processed as part of the data stream.
// tuser as used in eth_interface is the number of valid bytes
// Converting tuser to tkeep for ingress packets
assign e2c_tkeep = ~e2c_tlast ? 8'b1111_1111
: (e2c_tuser[2:0] == 3'd0) ? 8'b1111_1111
: (e2c_tuser[2:0] == 3'd1) ? 8'b0000_0001
: (e2c_tuser[2:0] == 3'd2) ? 8'b0000_0011
: (e2c_tuser[2:0] == 3'd3) ? 8'b0000_0111
: (e2c_tuser[2:0] == 3'd4) ? 8'b0000_1111
: (e2c_tuser[2:0] == 3'd5) ? 8'b0001_1111
: (e2c_tuser[2:0] == 3'd6) ? 8'b0011_1111
: 8'b0111_1111;
// Converting tkeep to tuser for egress packets
assign c2e_tuser = ~c2e_tlast ? 4'd0
: (c2e_tkeep == 8'b1111_1111) ? 4'd0
: (c2e_tkeep == 8'b0111_1111) ? 4'd7
: (c2e_tkeep == 8'b0011_1111) ? 4'd6
: (c2e_tkeep == 8'b0001_1111) ? 4'd5
: (c2e_tkeep == 8'b0000_1111) ? 4'd4
: (c2e_tkeep == 8'b0000_0111) ? 4'd3
: (c2e_tkeep == 8'b0000_0011) ? 4'd2
: (c2e_tkeep == 8'b0000_0001) ? 4'd1
: 4'd0;
if (EN_RX_KV_MAP_CFG || EN_RX_RAW_PYLD) begin : gen_eth_ipv4_interface_wrapper
eth_ipv4_interface_wrapper #(
.PROTOVER (RFNOC_PROTOVER),
.NODE_INST (NODE_INST),
.REG_AWIDTH (AWIDTH),
.BASE (REG_BASE_ETH_SWITCH),
.SYNC (1),
.EN_RX_KV_MAP_CFG (EN_RX_KV_MAP_CFG),
.EN_RX_RAW_PYLD (EN_RX_RAW_PYLD)
) eth_ipv4_interface_wrapper_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),
.my_mac (),
.my_ip (),
.my_udp_chdr_port (),
.eth_clk (bus_clk),
.eth_rst (bus_rst),
.eth_pause_req (),
.eth_tx_tdata (sfpi_tdata),
.eth_tx_tuser (sfpi_tuser),
.eth_tx_tkeep (),
.eth_tx_tlast (sfpi_tlast),
.eth_tx_tvalid (sfpi_tvalid),
.eth_tx_tready (sfpi_tready),
.eth_rx_tdata (sfpo_tdata),
.eth_rx_tuser (sfpo_tuser),
.eth_rx_tlast (sfpo_tlast),
.eth_rx_tvalid (sfpo_tvalid),
.eth_rx_tready (sfpo_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),
.cpu_clk (bus_clk),
.cpu_rst (bus_rst),
.e2c_tdata (e2c_tdata),
.e2c_tuser (e2c_tuser),
.e2c_tlast (e2c_tlast),
.e2c_tvalid (e2c_tvalid),
.e2c_tready (e2c_tready),
.c2e_tdata (c2e_tdata),
.c2e_tuser (c2e_tuser),
.c2e_tlast (c2e_tlast),
.c2e_tvalid (c2e_tvalid),
.c2e_tready (c2e_tready)
);
end // gen_eth_ipv4_interface_wrapper
else begin : gen_eth_interface
eth_interface #(
.PROTOVER (RFNOC_PROTOVER),
.MTU (10),
.NODE_INST (NODE_INST),
.REG_AWIDTH (AWIDTH),
.BASE (REG_BASE_ETH_SWITCH)
) eth_interface (
.clk (bus_clk),
.reset (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),
.my_mac (),
.my_ip (),
.my_udp_port (),
.eth_tx_tdata (sfpi_tdata),
.eth_tx_tuser (sfpi_tuser),
.eth_tx_tlast (sfpi_tlast),
.eth_tx_tvalid (sfpi_tvalid),
.eth_tx_tready (sfpi_tready),
.eth_rx_tdata (sfpo_tdata),
.eth_rx_tuser (sfpo_tuser),
.eth_rx_tlast (sfpo_tlast),
.eth_rx_tvalid (sfpo_tvalid),
.eth_rx_tready (sfpo_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),
.e2c_tdata (e2c_tdata),
.e2c_tuser (e2c_tuser),
.e2c_tlast (e2c_tlast),
.e2c_tvalid (e2c_tvalid),
.e2c_tready (e2c_tready),
.c2e_tdata (c2e_tdata),
.c2e_tuser (c2e_tuser),
.c2e_tlast (c2e_tlast),
.c2e_tvalid (c2e_tvalid),
.c2e_tready (c2e_tready)
);
end // gen_eth_interface
end // gen_eth
endgenerate
endmodule // e320_sfp_wrapper
`default_nettype wire
-484
View File
@@ -1,484 +0,0 @@
///////////////////////////////////////////////////////////////////
//
// Copyright 2017 Ettus Research, A National Instruments Company
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Module: n3xx_sfp_wrapper
// Description:
// Reduces clutter at top level.
// - Aurora: wraps up sfpp_io, axil_regport and axi_dummy
// - 1/10G: wrapper around network interface
//
//////////////////////////////////////////////////////////////////////
module n3xx_sfp_wrapper #(
parameter PROTOCOL = "10GbE", // Must be {10GbE, 1GbE, Aurora, Disabled}
parameter DWIDTH = 32,
parameter AWIDTH = 14,
parameter [7:0] PORTNUM = 8'd0,
parameter MDIO_EN = 0,
parameter [4:0] MDIO_PHYADDR = 5'd0,
parameter [15:0] RFNOC_PROTOVER = {8'd1, 8'd0}
)(
// Resets
input areset,
input bus_rst,
// Clocks
input gt_refclk,
input gb_refclk,
input misc_clk,
input bus_clk,
// FIXME: Merge E320 and N310 files
input user_clk,
input sync_clk,
//Axi-lite
input s_axi_aclk,
input s_axi_aresetn,
input [AWIDTH-1:0] s_axi_awaddr,
input s_axi_awvalid,
output s_axi_awready,
input [DWIDTH-1:0] s_axi_wdata,
input [DWIDTH/8-1:0] s_axi_wstrb,
input s_axi_wvalid,
output s_axi_wready,
output [1:0] s_axi_bresp,
output s_axi_bvalid,
input s_axi_bready,
input [AWIDTH-1:0] s_axi_araddr,
input s_axi_arvalid,
output s_axi_arready,
output [DWIDTH-1:0] s_axi_rdata,
output [1:0] s_axi_rresp,
output s_axi_rvalid,
input s_axi_rready,
// SFP high-speed IO
output txp,
output txn,
input rxp,
input rxn,
// SFP low-speed IO
input sfpp_present_n,
input sfpp_rxlos,
input sfpp_tx_fault,
output sfpp_tx_disable,
//GT Common
input qpllrefclklost,
input qplllock,
input qplloutclk,
input qplloutrefclk,
output qpllreset,
//Aurora MMCM
input mmcm_locked,
output gt_pll_lock,
output gt_tx_out_clk_unbuf,
// Vita router interface
output [63:0] e2v_tdata,
output e2v_tlast,
output e2v_tvalid,
input e2v_tready,
input [63:0] v2e_tdata,
input v2e_tlast,
input v2e_tvalid,
output v2e_tready,
// CPU
output [63:0] e2c_tdata,
output [7:0] e2c_tkeep,
output e2c_tlast,
output e2c_tvalid,
input e2c_tready,
input [63:0] c2e_tdata,
input [7:0] c2e_tkeep,
input c2e_tlast,
input c2e_tvalid,
output c2e_tready,
// MISC
output [31:0] port_info,
input [15:0] device_id,
// Timebase Outputs
output sfp_pps,
output sfp_refclk,
// Sideband White Rabbit Control
input wr_reset_n,
input wr_refclk,
output wr_dac_sclk,
output wr_dac_din,
output wr_dac_clr_n,
output wr_dac_cs_n,
output wr_dac_ldac_n,
output wr_eeprom_scl_o,
input wr_eeprom_scl_i,
output wr_eeprom_sda_o,
input wr_eeprom_sda_i,
input wr_uart_rx,
output wr_uart_tx,
// WR AXI Control
output wr_axi_aclk,
input wr_axi_aresetn,
input [31:0] wr_axi_awaddr,
input wr_axi_awvalid,
output wr_axi_awready,
input [DWIDTH-1:0] wr_axi_wdata,
input [DWIDTH/8-1:0] wr_axi_wstrb,
input wr_axi_wvalid,
output wr_axi_wready,
output [1:0] wr_axi_bresp,
output wr_axi_bvalid,
input wr_axi_bready,
input [31:0] wr_axi_araddr,
input wr_axi_arvalid,
output wr_axi_arready,
output [DWIDTH-1:0] wr_axi_rdata,
output [1:0] wr_axi_rresp,
output wr_axi_rvalid,
input wr_axi_rready,
output wr_axi_rlast,
output link_up,
output activity
);
localparam REG_BASE_SFP_IO = 14'h0;
localparam REG_BASE_ETH_SWITCH = 14'h1000;
// AXI4-Lite to RegPort (PS to PL Register Access)
wire reg_wr_req;
wire [AWIDTH-1:0] reg_wr_addr;
wire [DWIDTH-1:0] reg_wr_data;
wire reg_rd_req;
wire [AWIDTH-1:0] reg_rd_addr;
wire reg_rd_resp, reg_rd_resp_io, reg_rd_resp_eth_if;
wire [DWIDTH-1:0] reg_rd_data, reg_rd_data_io, reg_rd_data_eth_if;
axil_regport_master #(
.DWIDTH (DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
.AWIDTH (AWIDTH), // 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
) sfp_reg_mst_i (
// Clock and reset
.s_axi_aclk (s_axi_aclk),
.s_axi_aresetn (s_axi_aresetn),
// AXI4-Lite: Write address port (domain: s_axi_aclk)
.s_axi_awaddr (s_axi_awaddr),
.s_axi_awvalid (s_axi_awvalid),
.s_axi_awready (s_axi_awready),
// AXI4-Lite: Write data port (domain: s_axi_aclk)
.s_axi_wdata (s_axi_wdata),
.s_axi_wstrb (s_axi_wstrb),
.s_axi_wvalid (s_axi_wvalid),
.s_axi_wready (s_axi_wready),
// AXI4-Lite: Write response port (domain: s_axi_aclk)
.s_axi_bresp (s_axi_bresp),
.s_axi_bvalid (s_axi_bvalid),
.s_axi_bready (s_axi_bready),
// AXI4-Lite: Read address port (domain: s_axi_aclk)
.s_axi_araddr (s_axi_araddr),
.s_axi_arvalid (s_axi_arvalid),
.s_axi_arready (s_axi_arready),
// AXI4-Lite: Read data port (domain: s_axi_aclk)
.s_axi_rdata (s_axi_rdata),
.s_axi_rresp (s_axi_rresp),
.s_axi_rvalid (s_axi_rvalid),
.s_axi_rready (s_axi_rready),
// 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),
// 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 (DWIDTH),
.NUM_SLAVES (2)
) reg_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)
);
wire [63:0] sfpo_tdata, sfpi_tdata;
wire [3:0] sfpo_tuser, sfpi_tuser;
wire sfpo_tlast, sfpi_tlast, sfpo_tvalid, sfpi_tvalid, sfpo_tready, sfpi_tready;
generate
if (PROTOCOL != "WhiteRabbit") begin
n3xx_mgt_io_core #(
.PROTOCOL (PROTOCOL),
.REG_BASE (REG_BASE_SFP_IO),
.REG_DWIDTH (DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
.REG_AWIDTH (AWIDTH), // Width of the address bus
.MDIO_EN (MDIO_EN),
.MDIO_PHYADDR (MDIO_PHYADDR),
.PORTNUM (PORTNUM)
) mgt_io_i (
//must reset all channels on quad when sfp1 gtx core is reset
.areset (areset),
.gt_refclk (gt_refclk),
.gb_refclk (gb_refclk),
.misc_clk (misc_clk),
.bus_rst (bus_rst),
.bus_clk (bus_clk),
.txp (txp),
.txn (txn),
.rxp (rxp),
.rxn (rxn),
.sfpp_rxlos (sfpp_rxlos),
.sfpp_tx_fault (sfpp_tx_fault),
.sfpp_tx_disable(sfpp_tx_disable),
//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),
// Vita to Ethernet
.s_axis_tdata (sfpi_tdata),
.s_axis_tuser (sfpi_tuser),
.s_axis_tlast (sfpi_tlast),
.s_axis_tvalid (sfpi_tvalid),
.s_axis_tready (sfpi_tready),
// Ethernet to Vita
.m_axis_tdata (sfpo_tdata),
.m_axis_tuser (sfpo_tuser),
.m_axis_tlast (sfpo_tlast),
.m_axis_tvalid (sfpo_tvalid),
.m_axis_tready (sfpo_tready),
.port_info (port_info),
.link_up (link_up),
.activity (activity)
);
end else begin
//---------------------------------------------------------------------------------
// White Rabbit
//---------------------------------------------------------------------------------
wire wr_sfp_scl, wr_sfp_sda_o, wr_sfp_sda_i;
n3xx_wr_top #(
.g_simulation(1'b0), // in std_logic
.g_dpram_size(131072/4),
.g_dpram_initf("../../../../bin/wrpc/wrc_phy16.bram")
) wr_inst (
.areset_n_i (wr_reset_n), // in std_logic; -- active low reset, optional
.wr_refclk_buf_i (wr_refclk), // in std_logic; -- 20MHz VCXO after IBUFGDS
.gige_refclk_buf_i (gt_refclk), // in std_logic; -- 125 MHz MGT Ref after IBUFDS_GTE2
.dac_sclk_o (wr_dac_sclk), // out std_logic; -- N3xx cWB-DAC-SCLK
.dac_din_o (wr_dac_din), // out std_logic; -- N3xx cWB-DAC-DIN
.dac_clr_n_o (wr_dac_clr_n), // out std_logic; -- N3xx cWB-DAC-nCLR
.dac_cs_n_o (wr_dac_cs_n), // out std_logic; -- N3xx cWB-DAC-nSYNC
.dac_ldac_n_o (wr_dac_ldac_n), // out std_logic; -- N3xx cWB-DAC-nLDAC
.LED_ACT (activity), // out std_logic; -- connect to SFP+ ACT
.LED_LINK (link_up), // out std_logic; -- connect to SFP+ LINK
.sfp_txp_o (txp), // out std_logic;
.sfp_txn_o (txn), // out std_logic;
.sfp_rxp_i (rxp), // in std_logic;
.sfp_rxn_i (rxn), // in std_logic;
.sfp_mod_def0_b (sfpp_present_n), // in std_logic; - sfp detect
.eeprom_scl_o (wr_eeprom_scl_o),
.eeprom_scl_i (wr_eeprom_scl_i),
.eeprom_sda_o (wr_eeprom_sda_o),
.eeprom_sda_i (wr_eeprom_sda_i),
.sfp_scl_o (wr_sfp_scl),
.sfp_scl_i (wr_sfp_scl),
.sfp_sda_o (wr_sfp_sda_o),
.sfp_sda_i (wr_sfp_sda_i),
.sfp_tx_fault_i (sfpp_tx_fault), // in std_logic;
.sfp_tx_disable_o (sfpp_tx_disable), // out std_logic;
.sfp_los_i (sfpp_rxlos), // in std_logic;
.wr_uart_rxd (wr_uart_rx), // in std_logic;
.wr_uart_txd (wr_uart_tx), // out std_logic;
.s00_axi_aclk_o (wr_axi_aclk),
.s00_axi_aresetn (wr_axi_aresetn),
.s00_axi_awaddr (wr_axi_awaddr),
.s00_axi_awprot (3'b0),
.s00_axi_awvalid (wr_axi_awvalid),
.s00_axi_awready (wr_axi_awready),
.s00_axi_wdata (wr_axi_wdata),
.s00_axi_wstrb (wr_axi_wstrb),
.s00_axi_wvalid (wr_axi_wvalid),
.s00_axi_wready (wr_axi_wready),
.s00_axi_bresp (wr_axi_bresp),
.s00_axi_bvalid (wr_axi_bvalid),
.s00_axi_bready (wr_axi_bready),
.s00_axi_araddr (wr_axi_araddr),
.s00_axi_arprot (3'b0),
.s00_axi_arvalid (wr_axi_arvalid),
.s00_axi_arready (wr_axi_arready),
.s00_axi_rdata (wr_axi_rdata),
.s00_axi_rresp (wr_axi_rresp),
.s00_axi_rvalid (wr_axi_rvalid),
.s00_axi_rready (wr_axi_rready),
.s00_axi_rlast (wr_axi_rlast),
.axi_int_o (),
.pps_o (sfp_pps), // out std_logic;
.clk_pps_o (sfp_refclk), // out std_logic;
.link_ok_o (), // out std_logic;
.clk_sys_locked_o (), // out std_logic;
.clk_dmtd_locked_o (), // out std_logic);
.wr_debug0_o (),
.wr_debug1_o ()
);
// TEMPORARY mimic the AXGE SFP EEROM
sfp_eeprom sfp_eeprom_i (
.clk_i(bus_clk),
.sfp_scl(wr_sfp_scl),
.sfp_sda_i(wr_sfp_sda_o),
.sfp_sda_o(wr_sfp_sda_i));
// Assign the port_info vector similarly to mgt_io_core
localparam [7:0] COMPAT_NUM = 8'd2;
localparam [7:0] MGT_PROTOCOL = 8'd4;
assign port_info = {COMPAT_NUM, 6'h0, activity, link_up, MGT_PROTOCOL, PORTNUM};
// Tie off unused outputs.
assign gt_pll_lock = 1'b0;
assign gt_tx_out_clk_unbuf = 1'b0;
end
endgenerate
generate
// Tie off the Ethernet switch for these protocols that do not use it.
if(PROTOCOL == "Aurora" || PROTOCOL == "Disabled" || PROTOCOL == "WhiteRabbit") begin
//set unused wires to default value
assign e2c_tdata = 64'h0;
assign e2c_tkeep = 8'h0;
assign e2c_tlast = 1'b0;
assign e2c_tvalid = 1'b0;
assign c2e_tready = 1'b1;
assign reg_rd_resp_eth_if = 1'b0;
assign reg_rd_data_eth_if = 'h0;
end else begin
wire [3:0] e2c_tuser;
wire [3:0] c2e_tuser;
// In AXI Stream, tkeep is the byte qualifier that indicates
// whether the content of the associated byte
// of TDATA is processed as part of the data stream.
// tuser as used in eth_interface is the number of valid bytes
// Converting tuser to tkeep for ingress packets
assign e2c_tkeep = ~e2c_tlast ? 8'b1111_1111
: (e2c_tuser == 4'd0) ? 8'b1111_1111
: (e2c_tuser == 4'd1) ? 8'b0000_0001
: (e2c_tuser == 4'd2) ? 8'b0000_0011
: (e2c_tuser == 4'd3) ? 8'b0000_0111
: (e2c_tuser == 4'd4) ? 8'b0000_1111
: (e2c_tuser == 4'd5) ? 8'b0001_1111
: (e2c_tuser == 4'd6) ? 8'b0011_1111
: 8'b0111_1111;
// Converting tkeep to tuser for egress packets
assign c2e_tuser = ~c2e_tlast ? 4'd0
: (c2e_tkeep == 8'b1111_1111) ? 4'd0
: (c2e_tkeep == 8'b0111_1111) ? 4'd7
: (c2e_tkeep == 8'b0011_1111) ? 4'd6
: (c2e_tkeep == 8'b0001_1111) ? 4'd5
: (c2e_tkeep == 8'b0000_1111) ? 4'd4
: (c2e_tkeep == 8'b0000_0111) ? 4'd3
: (c2e_tkeep == 8'b0000_0011) ? 4'd2
: (c2e_tkeep == 8'b0000_0001) ? 4'd1
: 4'd0;
eth_interface #(
.PROTOVER (RFNOC_PROTOVER),
.MTU (10),
.NODE_INST (0),
.REG_AWIDTH (AWIDTH),
.BASE (REG_BASE_ETH_SWITCH)
) eth_interface (
.clk (bus_clk),
.reset (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),
.my_mac (),
.my_ip (),
.my_udp_port (),
.eth_tx_tdata (sfpi_tdata),
.eth_tx_tuser (sfpi_tuser),
.eth_tx_tlast (sfpi_tlast),
.eth_tx_tvalid (sfpi_tvalid),
.eth_tx_tready (sfpi_tready),
.eth_rx_tdata (sfpo_tdata),
.eth_rx_tuser (sfpo_tuser),
.eth_rx_tlast (sfpo_tlast),
.eth_rx_tvalid (sfpo_tvalid),
.eth_rx_tready (sfpo_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),
.e2c_tdata (e2c_tdata),
.e2c_tuser (e2c_tuser),
.e2c_tlast (e2c_tlast),
.e2c_tvalid (e2c_tvalid),
.e2c_tready (e2c_tready),
.c2e_tdata (c2e_tdata),
.c2e_tuser (c2e_tuser),
.c2e_tlast (c2e_tlast),
.c2e_tvalid (c2e_tvalid),
.c2e_tready (c2e_tready)
);
end
endgenerate
endmodule // n310_sfp_wrapper