Unused CHDR port was not being drained of discovery packets. Original-commit: 8d57586d61356c42a80408b6bd71e8f74a8d40e2
457 lines
16 KiB
Verilog
457 lines
16 KiB
Verilog
///////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright 2018 Ettus Research, A National Instruments Company
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
// Module: n3xx_mgt_wrapper
|
|
// Description:
|
|
// Provides wrapper for just the pieces specific to an MGT lane
|
|
// (for easy use with generate)
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
`default_nettype none
|
|
module n3xx_mgt_wrapper #(
|
|
parameter PROTOCOL = "10GbE", // Must be {10GbE, Aurora, Disabled}
|
|
parameter REG_DWIDTH = 32,
|
|
parameter REG_AWIDTH = 14,
|
|
parameter GT_COMMON = 1,
|
|
parameter [7:0] PORTNUM = 8'd0,
|
|
parameter MDIO_EN = 0,
|
|
parameter [4:0] MDIO_PHYADDR = 5'd0,
|
|
parameter REG_BASE = 16'h0000
|
|
)(
|
|
// 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,
|
|
input wire user_clk,
|
|
input wire sync_clk,
|
|
|
|
// RegPort interface
|
|
input wire reg_wr_req,
|
|
input wire [REG_AWIDTH-1:0] reg_wr_addr,
|
|
input wire [REG_DWIDTH-1:0] reg_wr_data,
|
|
input wire reg_rd_req,
|
|
input wire [REG_AWIDTH-1:0] reg_rd_addr,
|
|
output wire reg_rd_resp,
|
|
output wire [REG_DWIDTH-1:0] reg_rd_data,
|
|
|
|
// High-speed IO
|
|
output wire txp,
|
|
output wire txn,
|
|
input wire rxp,
|
|
input wire rxn,
|
|
|
|
// SFP low-speed IO
|
|
input wire mod_present_n,
|
|
input wire mod_rxlos,
|
|
input wire mod_tx_fault,
|
|
output wire mod_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,
|
|
|
|
// Vita router interface
|
|
output wire [63:0] e2v_tdata,
|
|
output wire e2v_tlast,
|
|
output wire e2v_tvalid,
|
|
input wire e2v_tready,
|
|
|
|
input wire [63:0] v2e_tdata,
|
|
input wire v2e_tlast,
|
|
input wire v2e_tvalid,
|
|
output wire v2e_tready,
|
|
|
|
// 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,
|
|
|
|
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,
|
|
|
|
// Timebase Outputs
|
|
output wire mod_pps,
|
|
output wire mod_refclk,
|
|
|
|
// Sideband White Rabbit Control
|
|
input wire wr_reset_n,
|
|
input wire wr_refclk,
|
|
|
|
output wire wr_dac_sclk,
|
|
output wire wr_dac_din,
|
|
output wire wr_dac_clr_n,
|
|
output wire wr_dac_cs_n,
|
|
output wire wr_dac_ldac_n,
|
|
|
|
output wire wr_eeprom_scl_o,
|
|
input wire wr_eeprom_scl_i,
|
|
output wire wr_eeprom_sda_o,
|
|
input wire wr_eeprom_sda_i,
|
|
|
|
input wire wr_uart_rx,
|
|
output wire wr_uart_tx,
|
|
|
|
// WR AXI Control
|
|
output wire wr_axi_aclk,
|
|
input wire wr_axi_aresetn,
|
|
input wire [31:0] wr_axi_awaddr,
|
|
input wire wr_axi_awvalid,
|
|
output wire wr_axi_awready,
|
|
input wire [REG_DWIDTH-1:0] wr_axi_wdata,
|
|
input wire [REG_DWIDTH/8-1:0] wr_axi_wstrb,
|
|
input wire wr_axi_wvalid,
|
|
output wire wr_axi_wready,
|
|
output wire [1:0] wr_axi_bresp,
|
|
output wire wr_axi_bvalid,
|
|
input wire wr_axi_bready,
|
|
input wire [31:0] wr_axi_araddr,
|
|
input wire wr_axi_arvalid,
|
|
output wire wr_axi_arready,
|
|
output wire [REG_DWIDTH-1:0] wr_axi_rdata,
|
|
output wire [1:0] wr_axi_rresp,
|
|
output wire wr_axi_rvalid,
|
|
input wire wr_axi_rready,
|
|
output wire wr_axi_rlast,
|
|
|
|
output wire link_up,
|
|
output wire activity
|
|
|
|
);
|
|
|
|
localparam [REG_AWIDTH-1:0] REG_BASE_MGT_IO = {REG_AWIDTH{1'b0}} + REG_BASE;
|
|
localparam [REG_AWIDTH-1:0] REG_BASE_ETH_SWITCH = {REG_AWIDTH{1'b0}} + 16'h1000 + REG_BASE;
|
|
|
|
// AXI4-Lite to RegPort (PS to PL Register Access)
|
|
wire reg_rd_resp_io, reg_rd_resp_eth_if;
|
|
wire [REG_DWIDTH-1:0] reg_rd_data_io, reg_rd_data_eth_if;
|
|
|
|
// Regport Mux for response
|
|
regport_resp_mux #(
|
|
.WIDTH (REG_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] mgto_tdata, mgti_tdata;
|
|
wire [3:0] mgto_tuser, mgti_tuser;
|
|
wire mgto_tlast, mgti_tlast, mgto_tvalid, mgti_tvalid, mgto_tready, mgti_tready;
|
|
|
|
generate
|
|
if (PROTOCOL != "WhiteRabbit") begin
|
|
n3xx_mgt_io_core #(
|
|
.PROTOCOL (PROTOCOL),
|
|
.REG_BASE (REG_BASE_MGT_IO),
|
|
.REG_DWIDTH (REG_DWIDTH), // Width of the AXI4-Lite data bus (must be 32 or 64)
|
|
.REG_AWIDTH (REG_AWIDTH), // Width of the address bus
|
|
.GT_COMMON (GT_COMMON),
|
|
.MDIO_EN (MDIO_EN),
|
|
.MDIO_PHYADDR (MDIO_PHYADDR),
|
|
.PORTNUM (PORTNUM)
|
|
) mgt_io_i (
|
|
//must reset all channels on quad when other gtx core is reset
|
|
.areset (areset),
|
|
.gt_refclk (gt_refclk),
|
|
.gb_refclk (gb_refclk),
|
|
.misc_clk (misc_clk),
|
|
.user_clk (user_clk),
|
|
.sync_clk (sync_clk),
|
|
.gt_tx_out_clk_unbuf(gt_tx_out_clk_unbuf),
|
|
|
|
.bus_rst (bus_rst),
|
|
.bus_clk (bus_clk),
|
|
.qpllreset (qpllreset),
|
|
.qplllock (qplllock),
|
|
.qplloutclk (qplloutclk),
|
|
.qplloutrefclk (qplloutrefclk),
|
|
.qpllrefclklost (qpllrefclklost),
|
|
.mmcm_locked (mmcm_locked),
|
|
.gt_pll_lock (gt_pll_lock),
|
|
|
|
.txp (txp),
|
|
.txn (txn),
|
|
.rxp (rxp),
|
|
.rxn (rxn),
|
|
|
|
.sfpp_rxlos (mod_rxlos),
|
|
.sfpp_tx_fault (mod_tx_fault),
|
|
.sfpp_tx_disable(mod_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 (mgti_tdata),
|
|
.s_axis_tuser (mgti_tuser),
|
|
.s_axis_tlast (mgti_tlast),
|
|
.s_axis_tvalid (mgti_tvalid),
|
|
.s_axis_tready (mgti_tready),
|
|
|
|
// Ethernet to Vita
|
|
.m_axis_tdata (mgto_tdata),
|
|
.m_axis_tuser (mgto_tuser),
|
|
.m_axis_tlast (mgto_tlast),
|
|
.m_axis_tvalid (mgto_tvalid),
|
|
.m_axis_tready (mgto_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 (mod_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 (mod_tx_fault), // in std_logic;
|
|
.sfp_tx_disable_o (mod_tx_disable), // out std_logic;
|
|
.sfp_los_i (mod_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 (mod_pps), // out std_logic;
|
|
.clk_pps_o (mod_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") begin
|
|
// Set unused wires to default values
|
|
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;
|
|
|
|
assign e2v_tdata = mgto_tdata;
|
|
assign e2v_tlast = mgto_tlast;
|
|
assign e2v_tvalid = mgto_tvalid;
|
|
assign mgto_tready = e2v_tready;
|
|
|
|
assign mgti_tdata = v2e_tdata;
|
|
assign mgti_tlast = v2e_tlast;
|
|
assign mgti_tvalid = v2e_tvalid;
|
|
assign v2e_tready = mgti_tready;
|
|
|
|
end else if(PROTOCOL == "WhiteRabbit") begin
|
|
// Set unused wires to default values
|
|
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;
|
|
|
|
assign e2v_tdata = 64'b0;
|
|
assign e2v_tlast = 1'b0;
|
|
assign e2v_tvalid = 1'b0;
|
|
|
|
assign v2e_tready = 1'b1;
|
|
|
|
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_switch is the numbier 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 ({8'd1,8'd0}), //FIXME. This should come from outside
|
|
.MTU (10),
|
|
.NODE_INST (0),
|
|
.REG_AWIDTH (REG_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 (mgti_tdata),
|
|
.eth_tx_tuser (mgti_tuser),
|
|
.eth_tx_tlast (mgti_tlast),
|
|
.eth_tx_tvalid (mgti_tvalid),
|
|
.eth_tx_tready (mgti_tready),
|
|
.eth_rx_tdata (mgto_tdata),
|
|
.eth_rx_tuser (mgto_tuser),
|
|
.eth_rx_tlast (mgto_tlast),
|
|
.eth_rx_tvalid (mgto_tvalid),
|
|
.eth_rx_tready (mgto_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 // n3xx_mgt_wrapper
|
|
`default_nettype wire
|