fpga: lib: Add NET_CHDR_W parameter to transport adapters
The NET_CHDR_W parameter tells the transport adapter what CHDR width is used in transport packets, such as Ethernet packets. By default the CHDR width used by the transport and RFNoC core will be the same. The NET_CHDR_W parameter can be used in situations where the RFNoC core expects a CHDR width from the transport adapter that is different from that used over the network. In this situation, the transport adapter will rewrite the CHDR packets so that each side gets the expected CHDR width. Original-commit: a9e49b7c587ef778ee0fe327e8bdcb15e0b0fc95
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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 ),
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user