aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/e320/n3xx_sfp_wrapper.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/e320/n3xx_sfp_wrapper.v')
-rw-r--r--fpga/usrp3/top/e320/n3xx_sfp_wrapper.v484
1 files changed, 484 insertions, 0 deletions
diff --git a/fpga/usrp3/top/e320/n3xx_sfp_wrapper.v b/fpga/usrp3/top/e320/n3xx_sfp_wrapper.v
new file mode 100644
index 000000000..5067b1727
--- /dev/null
+++ b/fpga/usrp3/top/e320/n3xx_sfp_wrapper.v
@@ -0,0 +1,484 @@
+///////////////////////////////////////////////////////////////////
+//
+// 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