aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/n3xx/n3xx_mgt_wrapper.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/n3xx/n3xx_mgt_wrapper.v')
-rw-r--r--fpga/usrp3/top/n3xx/n3xx_mgt_wrapper.v440
1 files changed, 440 insertions, 0 deletions
diff --git a/fpga/usrp3/top/n3xx/n3xx_mgt_wrapper.v b/fpga/usrp3/top/n3xx/n3xx_mgt_wrapper.v
new file mode 100644
index 000000000..fa1d5fe5d
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/n3xx_mgt_wrapper.v
@@ -0,0 +1,440 @@
+///////////////////////////////////////////////////////////////////
+//
+// 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" || 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;
+
+ 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 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