Files
b210-k7-fpga/top/e320/n3xx_sfp_wrapper.v
T
+18 6b67702ad7 Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce
the size of the repository. However, over the last half-decade, the
split between the repositories has proven more burdensome than it has
been helpful. By merging the FPGA code back, it will be possible to
create atomic commits that touch both FPGA and UHD codebases. Continuous
integration testing is also simplified by merging the repositories,
because it was previously difficult to automatically derive the correct
UHD branch when testing a feature branch on the FPGA repository.

This commit also updates the license files and paths therein.

We are therefore merging the repositories again. Future development for
FPGA code will happen in the same repository as the UHD host code and
MPM code.

== Original Codebase and Rebasing ==

The original FPGA repository will be hosted for the foreseeable future
at its original local location: https://github.com/EttusResearch/fpga/

It can be used for bisecting, reference, and a more detailed history.

The final commit from said repository to be merged here is
05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as
v4.0.0.0-pre-uhd-merge.

If you have changes in the FPGA repository that you want to rebase onto
the UHD repository, simply run the following commands:

- Create a directory to store patches (this should be an empty
  directory):

    mkdir ~/patches

- Now make sure that your FPGA codebase is based on the same state as
  the code that was merged:

    cd src/fpga # Or wherever your FPGA code is stored
    git rebase v4.0.0.0-pre-uhd-merge

  Note: The rebase command may look slightly different depending on what
  exactly you're trying to rebase.

- Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge:

    git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches

  Note: Make sure that only patches are stored in your output directory.
  It should otherwise be empty. Make sure that you picked the correct
  range of commits, and only commits you wanted to rebase were exported
  as patch files.

- Go to the UHD repository and apply the patches:

    cd src/uhd # Or wherever your UHD repository is stored
    git am --directory fpga ~/patches/*
    rm -rf ~/patches # This is for cleanup

== Contributors ==

The following people have contributed mainly to these files (this list
is not complete):

Co-authored-by: Alex Williams <alex.williams@ni.com>
Co-authored-by: Andrej Rode <andrej.rode@ettus.com>
Co-authored-by: Ashish Chaudhari <ashish@ettus.com>
Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com>
Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Derek Kozel <derek.kozel@ettus.com>
Co-authored-by: EJ Kreinar <ej@he360.com>
Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com>
Co-authored-by: Ian Buckley <ian.buckley@gmail.com>
Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Jon Kiser <jon.kiser@ni.com>
Co-authored-by: Josh Blum <josh@joshknows.com>
Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Matt Ettus <matt@ettus.com>
Co-authored-by: Michael West <michael.west@ettus.com>
Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com>
Co-authored-by: Nick Foster <nick@ettus.com>
Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Paul David <paul.david@ettus.com>
Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com>
Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-authored-by: Sylvain Munaut <tnt@246tNt.com>
Co-authored-by: Trung Tran <trung.tran@ettus.com>
Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>


Original-commit: bafa9d95453387814ef25e6b6256ba8db2df612f
2020-01-28 09:35:36 -08:00

485 lines
16 KiB
Verilog

///////////////////////////////////////////////////////////////////
//
// 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