diff --git a/lib/rfnoc/xport_sv/chdr_xport_adapter.sv b/lib/rfnoc/xport_sv/chdr_xport_adapter.sv index 1782151..3246488 100644 --- a/lib/rfnoc/xport_sv/chdr_xport_adapter.sv +++ b/lib/rfnoc/xport_sv/chdr_xport_adapter.sv @@ -24,6 +24,7 @@ // - NODE_INST: The node type to return for a node-info discovery // - ALLOW_DISC: Controls if the external transport network should be // discoverable by management packets from RFNoC side. +// - NET_CHDR_W: CHDR width used over the network connection // // Signals: // - device_id : The ID of the device that has instantiated this module @@ -43,8 +44,9 @@ module chdr_xport_adapter #( int TBL_SIZE = 6, logic [7:0] NODE_SUBTYPE = NODE_SUBTYPE_XPORT_IPV4_CHDR64, int NODE_INST = 0, - bit ALLOW_DISC = 1 -)( + bit ALLOW_DISC = 1, + int NET_CHDR_W = 64 +) ( // Device info (domain: eth_rx.clk) input logic [15:0] device_id, // Device addresses (domain: eth_rx.clk) @@ -90,6 +92,8 @@ module chdr_xport_adapter #( // tUser={udp_src_port,ipv4_src_addr,eth_src_addr} AxiStreamIf #(.DATA_WIDTH(eth_rx.DATA_WIDTH),.USER_WIDTH(USER_META_W),.TKEEP(0)) e2d(eth_rx.clk,eth_rx.rst);// Eth => Demux + AxiStreamIf #(.DATA_WIDTH(eth_rx.DATA_WIDTH),.USER_WIDTH(USER_META_W),.TKEEP(0)) + e2v_resize(eth_rx.clk,eth_rx.rst);// RX Resize => Management packet handler logic [1:0] e2d_tid; // tUser={udp_src_port,ipv4_src_addr,eth_src_addr} AxiStreamIf #(.DATA_WIDTH(eth_rx.DATA_WIDTH),.USER_WIDTH(USER_META_W),.TKEEP(0)) @@ -155,11 +159,42 @@ module chdr_xport_adapter #( .m_axis_tlast(ru4.tlast), .m_axis_tvalid(ru4.tvalid), .m_axis_tready(ru4.tready) ); - // Pay close attention to when ph.tuser swtiches versus when it is needed! + // Pay close attention to when ph.tuser switches versus when it is needed! always_comb begin : assign_ph `AXI4S_ASSIGN(ph,ru4) end + // --------------------------------------------------- + // Rewrite packets from network to use FPGA CHDR_W + // --------------------------------------------------- + if (NET_CHDR_W != eth_rx.DATA_WIDTH) begin : gen_chdr_resize_e2v + chdr_resize #( + .I_CHDR_W (NET_CHDR_W), + .O_CHDR_W (eth_rx.DATA_WIDTH), + .I_DATA_W (eth_rx.DATA_WIDTH), + .O_DATA_W (eth_rx.DATA_WIDTH), + .USER_W (USER_META_W), + .PIPELINE ("IN") + ) chdr_resize_e2v ( + .clk (eth_rx.clk), + .rst (eth_rx.rst), + .i_chdr_tdata (ph.tdata), + .i_chdr_tuser (ph.tuser), + .i_chdr_tlast (ph.tlast), + .i_chdr_tvalid (ph.tvalid), + .i_chdr_tready (ph.tready), + .o_chdr_tdata (e2v_resize.tdata), + .o_chdr_tuser (e2v_resize.tuser), + .o_chdr_tlast (e2v_resize.tlast), + .o_chdr_tvalid (e2v_resize.tvalid), + .o_chdr_tready (e2v_resize.tready) + ); + end else begin : gen_no_chdr_resize_e2v + always_comb begin + `AXI4S_ASSIGN(e2v_resize, ph); + end + end + // --------------------------------------------------- // Transport => DEMUX // --------------------------------------------------- @@ -181,9 +216,9 @@ module chdr_xport_adapter #( .clk(eth_rx.clk), .rst(eth_rx.rst), .node_info(node_info), //ph in - .s_axis_chdr_tdata(ph.tdata), .s_axis_chdr_tlast(ph.tlast), - .s_axis_chdr_tvalid(ph.tvalid), .s_axis_chdr_tready(ph.tready), - .s_axis_chdr_tuser(ph.tuser), + .s_axis_chdr_tdata(e2v_resize.tdata), .s_axis_chdr_tlast(e2v_resize.tlast), + .s_axis_chdr_tvalid(e2v_resize.tvalid), .s_axis_chdr_tready(e2v_resize.tready), + .s_axis_chdr_tuser(e2v_resize.tuser), //e2d out .m_axis_chdr_tdata(e2d.tdata), .m_axis_chdr_tlast(e2d.tlast), .m_axis_chdr_tdest(/* unused */), .m_axis_chdr_tid(e2d_tid), @@ -335,7 +370,9 @@ module chdr_xport_adapter #( // one packet per lookup after the lookup is complete. AxiStreamIf #(.DATA_WIDTH(eth_rx.DATA_WIDTH),.TUSER(0),.TKEEP(0)) - data_fifo_o(eth_rx.clk,eth_rx.rst); + resize_v2e(eth_rx.clk,eth_rx.rst); + AxiStreamIf #(.DATA_WIDTH(eth_rx.DATA_WIDTH),.USER_WIDTH(0),.TKEEP(0)) + data_fifo_o(eth_rx.clk,eth_rx.rst);// TX Resize => Management packet handler AxiStreamIf #(.DATA_WIDTH(eth_rx.DATA_WIDTH),.TUSER(0),.TKEEP(0)) data_fifo_i(eth_rx.clk,eth_rx.rst); @@ -348,7 +385,7 @@ module chdr_xport_adapter #( logic [USER_META_W-1:0] lookup_fifo_tuser; logic [ 15:0] lookup_fifo_tepid; logic non_lookup_done_stb; - logic data_fifo_o_hdr = 1'b1; + logic resize_v2e_hdr = 1'b1; logic pass_packet; logic [USER_META_W-1:0] result_tuser; logic result_tuser_valid; @@ -389,6 +426,37 @@ module chdr_xport_adapter #( .occupied () ); + // --------------------------------------------------- + // Rewrite packets from FPGA to use network CHDR_W + // --------------------------------------------------- + if (NET_CHDR_W != eth_rx.DATA_WIDTH) begin : gen_chdr_resize_v2e + chdr_resize #( + .I_CHDR_W (eth_rx.DATA_WIDTH), + .O_CHDR_W (NET_CHDR_W), + .I_DATA_W (eth_rx.DATA_WIDTH), + .O_DATA_W (eth_rx.DATA_WIDTH), + .USER_W (1), + .PIPELINE ("OUT") + ) chdr_resize_v2e ( + .clk (eth_rx.clk), + .rst (eth_rx.rst), + .i_chdr_tdata (data_fifo_o.tdata), + .i_chdr_tuser (1'b0), + .i_chdr_tlast (data_fifo_o.tlast), + .i_chdr_tvalid (data_fifo_o.tvalid), + .i_chdr_tready (data_fifo_o.tready), + .o_chdr_tdata (resize_v2e.tdata), + .o_chdr_tuser (), + .o_chdr_tlast (resize_v2e.tlast), + .o_chdr_tvalid (resize_v2e.tvalid), + .o_chdr_tready (resize_v2e.tready) + ); + end else begin : gen_no_chdr_resize_v2e + always_comb begin + `AXI4S_ASSIGN(resize_v2e, data_fifo_o); + end + end + // The lookup FIFO only takes the header routing info (tdest, tuser, epid). // We use axi_fifo_short since it can tolerate tvalid going low before a // transfer completes. @@ -443,12 +511,12 @@ module chdr_xport_adapter #( // Pop the routing info off of the lookup_fifo if we've started its lookup always_comb lookup_fifo_o.tready = lookup_stb || non_lookup_done_stb; - // Track when the next data_fifo_o word is the start of a new packet - always_ff @(posedge eth_rx.clk) begin : data_fifo_o_hdr_ff + // Track when the next resize_v2e word is the start of a new packet + always_ff @(posedge eth_rx.clk) begin : resize_v2e_hdr_ff if (eth_rx.rst) - data_fifo_o_hdr <= 1'b1; - else if (data_fifo_o.tvalid && data_fifo_o.tready && pass_packet) - data_fifo_o_hdr <= data_fifo_o.tlast; + resize_v2e_hdr <= 1'b1; + else if (resize_v2e.tvalid && resize_v2e.tready && pass_packet) + resize_v2e_hdr <= resize_v2e.tlast; end // Store the lookup result in a holding register. This can come from the KV @@ -460,7 +528,7 @@ module chdr_xport_adapter #( end else begin // The tuser holding register becomes available as soon as we start // transmitting the corresponding packet. - if (data_fifo_o.tvalid && data_fifo_o.tready && data_fifo_o_hdr && pass_packet) begin + if (resize_v2e.tvalid && resize_v2e.tready && resize_v2e_hdr && pass_packet) begin result_tuser_valid <= 1'b0; end @@ -483,13 +551,13 @@ module chdr_xport_adapter #( reg_o_tuser <= {USER_META_W{1'bX}}; // Don't care end else begin // We're done passing through a packet when tlast goes out - if (data_fifo_o.tvalid && data_fifo_o.tready && data_fifo_o.tlast && pass_packet) begin + if (resize_v2e.tvalid && resize_v2e.tready && resize_v2e.tlast && pass_packet) begin pass_packet <= 1'b0; end // We can pass the next packet through when we're at the start of a // packet and we have the tuser value waiting in the holding register. - if (data_fifo_o_hdr && result_tuser_valid && !pass_packet) begin + if (resize_v2e_hdr && result_tuser_valid && !pass_packet) begin reg_o_tuser <= result_tuser; pass_packet <= 1'b1; end @@ -505,10 +573,10 @@ module chdr_xport_adapter #( au(eth_rx.clk,eth_rx.rst);// Add UDP input always_comb begin {au_udp_dst,au_ip_dst,au_mac_dst} = reg_o_tuser; - au.tdata = data_fifo_o.tdata; - au.tlast = data_fifo_o.tlast; - au.tvalid = data_fifo_o.tvalid & pass_packet; - data_fifo_o.tready = au.tready & pass_packet; + au.tdata = resize_v2e.tdata; + au.tlast = resize_v2e.tlast; + au.tvalid = resize_v2e.tvalid & pass_packet; + resize_v2e.tready = au.tready & pass_packet; end // Clock Crossing to the ethernet clock domain diff --git a/lib/rfnoc/xport_sv/eth_ipv4_chdr_adapter.sv b/lib/rfnoc/xport_sv/eth_ipv4_chdr_adapter.sv index c452b16..0887ace 100644 --- a/lib/rfnoc/xport_sv/eth_ipv4_chdr_adapter.sv +++ b/lib/rfnoc/xport_sv/eth_ipv4_chdr_adapter.sv @@ -29,7 +29,8 @@ // Ethernet clock domain (eth_rx, eth_tx). // - ENET_W: Width of the link to the Ethernet MAC // - CPU_W: Width of the CPU interface -// - CHDR_W: Width of the CHDR interface +// - CHDR_W: CHDR width used by RFNoC on the FPGA +// - NET_CHDR_W: CHDR width used over the network connection // // Signals: // - device_id : The ID of the device that has instantiated this module @@ -57,7 +58,8 @@ module eth_ipv4_chdr_adapter #( bit SYNC = 0, int ENET_W = 64, int CPU_W = 64, - int CHDR_W = 64 + int CHDR_W = 64, + int NET_CHDR_W = CHDR_W )( // Device info @@ -80,7 +82,7 @@ module eth_ipv4_chdr_adapter #( // CHDR router interface (eth_rx.clk) AxiStreamIf.master e2v, // tUser = {*not used*}; AxiStreamIf.slave v2e, // tUser = {*not used*}; - + // CPU DMA // (domain: e2c.clk if SYNC=0, else eth_rx.clk) AxiStreamIf.master e2c, // tUser = {sof,trailing bytes}; @@ -137,13 +139,13 @@ module eth_ipv4_chdr_adapter #( // Ethernet sink. Inspects packet and dispatches // to the correct port. eth_ipv4_chdr_dispatch #( - .CPU_FIFO_SIZE(CPU_FIFO_SIZE), - .CHDR_FIFO_SIZE(CHDR_FIFO_SIZE), - .PREAMBLE_BYTES(PREAMBLE_BYTES), - .MAX_PACKET_BYTES(MAX_PACKET_BYTES), - .DROP_UNKNOWN_MAC(DROP_UNKNOWN_MAC), - .DROP_MIN_PACKET(DROP_MIN_PACKET), - .ENET_W(ENET_W) + .CPU_FIFO_SIZE (CPU_FIFO_SIZE), + .CHDR_FIFO_SIZE (CHDR_FIFO_SIZE), + .PREAMBLE_BYTES (PREAMBLE_BYTES), + .MAX_PACKET_BYTES (MAX_PACKET_BYTES), + .DROP_UNKNOWN_MAC (DROP_UNKNOWN_MAC), + .DROP_MIN_PACKET (DROP_MIN_PACKET), + .ENET_W (ENET_W) ) eth_dispatch_i ( .eth_pause_req (eth_pause_req), .eth_rx (eth_rx1), @@ -229,21 +231,21 @@ module eth_ipv4_chdr_adapter #( chdr_xport_adapter #( .PREAMBLE_BYTES (PREAMBLE_BYTES), .MAX_PACKET_BYTES (MAX_PACKET_BYTES), - .PROTOVER (PROTOVER), - .TBL_SIZE (RT_TBL_SIZE), - .NODE_INST (NODE_INST), - .ALLOW_DISC (1) + .PROTOVER (PROTOVER), + .TBL_SIZE (RT_TBL_SIZE), + .NODE_INST (NODE_INST), + .ALLOW_DISC (1), + .NET_CHDR_W (NET_CHDR_W) ) xport_adapter_gen_i ( - .device_id (device_id), - .my_mac (my_mac), - .my_ip (my_ip), - .my_udp_chdr_port (my_udp_chdr_port), - - .eth_rx (e2v2), // from ethernet - .e2v (e2v3), // to CHDR - // optional loop from ethernet to ethernet to talk to node - .v2e (v2e), // from CHDR - .eth_tx (v2e1D) // to ethernet + .device_id (device_id), + .my_mac (my_mac), + .my_ip (my_ip), + .my_udp_chdr_port (my_udp_chdr_port), + .eth_rx (e2v2), // from Ethernet + .e2v (e2v3), // to CHDR + // Optional loop from Ethernet to Ethernet to talk to node + .v2e (v2e), // from CHDR + .eth_tx (v2e1D) // to Ethernet ); if (DEBUG) begin @@ -317,7 +319,7 @@ module eth_ipv4_chdr_adapter #( if (ENET_W > CPU_W || !SYNC) begin : gen_c2e_packet_gate // Adding so packet will be contiguous going out - // I think the MAC needs bandwdith feeding it to + // I think the MAC needs bandwidth feeding it to // be greater than the line rate axi4s_packet_gate #(.SIZE(17-$clog2(ENET_W)), .USE_AS_BUFF(0)) c2e_gate_i (.clear(1'b0),.error(1'b0),.i(c2e1_0),.o(c2e1)); diff --git a/lib/rfnoc/xport_sv/eth_ipv4_interface.sv b/lib/rfnoc/xport_sv/eth_ipv4_interface.sv index 73ee3d9..f3a5d70 100644 --- a/lib/rfnoc/xport_sv/eth_ipv4_interface.sv +++ b/lib/rfnoc/xport_sv/eth_ipv4_interface.sv @@ -23,7 +23,8 @@ // Ethernet clock domain (eth_rx, eth_tx). // - ENET_W: Width of the link to the Ethernet MAC // - CPU_W: Width of the CPU interface -// - CHDR_W: Width of the CHDR interface +// - CHDR_W: CHDR width used by RFNoC on the FPGA +// - NET_CHDR_W: CHDR width used over the network connection // module eth_ipv4_interface #( @@ -42,7 +43,8 @@ module eth_ipv4_interface #( bit PAUSE_EN = 0, int ENET_W = 64, int CPU_W = 64, - int CHDR_W = 64 + int CHDR_W = 64, + int NET_CHDR_W = CHDR_W ) ( input logic bus_clk, input logic bus_rst, @@ -283,7 +285,8 @@ module eth_ipv4_interface #( .SYNC (SYNC), .ENET_W (ENET_W), .CPU_W (CPU_W), - .CHDR_W (CHDR_W) + .CHDR_W (CHDR_W), + .NET_CHDR_W (NET_CHDR_W) ) eth_adapter_i ( .eth_pause_req (eth_pause_req), .eth_rx (eth_rx ), diff --git a/lib/rfnoc/xport_sv/eth_ipv4_internal.sv b/lib/rfnoc/xport_sv/eth_ipv4_internal.sv index d4bc9d3..8166fda 100644 --- a/lib/rfnoc/xport_sv/eth_ipv4_internal.sv +++ b/lib/rfnoc/xport_sv/eth_ipv4_internal.sv @@ -5,7 +5,7 @@ // // Module: eth_ipv4_internal // -// Description: +// Description: // // This internal Ethernet port is responsible for routing CHDR data between // the ARM CPU and RFNoC. Treating the RFNoC interface to the CPU like an @@ -24,7 +24,8 @@ // // Parameters: // -// CHDR_W : CHDR width +// CHDR_W : CHDR width used by RFNoC on the FPGA +// NET_CHDR_W : CHDR width used over the network connection // BYTE_MTU : Sets the MTU to 2^BYTE_MTU bytes // DWIDTH : Data width for AXI-Lite interface (32 or 64) // AWIDTH : Address width for AXI-Lite interface @@ -37,6 +38,7 @@ module eth_ipv4_internal #( parameter CHDR_W = 64, + parameter NET_CHDR_W = CHDR_W, parameter BYTE_MTU = 10, parameter DWIDTH = 32, parameter AWIDTH = 14, @@ -286,7 +288,7 @@ module eth_ipv4_internal #( logic c2e_tvalid; logic c2e_tready; - localparam CPU_USER_W = $clog2(CPU_W/8)+1; // SOF + trailing bytes + localparam CPU_USER_W = $clog2(CPU_W/8)+1; // SOF + trailing bytes // Host DMA interfaces AxiStreamIf #(.DATA_WIDTH(CPU_W), .USER_WIDTH(CPU_USER_W), .TUSER(1), .TKEEP(0)) @@ -353,7 +355,8 @@ module eth_ipv4_internal #( .ADD_SOF (1), .ENET_W (CPU_W), .CPU_W (CPU_W), - .CHDR_W (CHDR_W) + .CHDR_W (CHDR_W), + .NET_CHDR_W (NET_CHDR_W) ) eth_ipv4_interface_i ( .bus_clk (bus_clk), .bus_rst (bus_rst), @@ -383,7 +386,7 @@ module eth_ipv4_internal #( //--------------------------------------------------------------------------- // // This block sends replies to ARP IPv4 frames. - // + // //--------------------------------------------------------------------------- arp_responder arp_responder_i ( @@ -414,7 +417,7 @@ module eth_ipv4_internal #( // our internal Ethernet port. Only the NIXGE_REG_LED_CTL register is // actually used, but the internal adapter doesn't need LED control. So all // registers read as 0 and all writes are ignored. - // + // //--------------------------------------------------------------------------- // NIXGE Registers