Files
b210-k7-fpga/lib/rfnoc/xport_sv/eth_ipv4_interface.sv
T
Andrew Moch 05eb1bc2f1 fpga: lib: Add width agnostic version of Ethernet Interface
The rnfoc/xport section is refactored in System Verilog to allow the
following improvements
(1) CPU_W - Sets the size of the c2e and e2c pipes.  This can be run
    at a different clock rate than the main ethernet pipe
(2) CHDR_W - Sets the size of the v2e and e2v pipes. This can be run
    at a different clock rate than the main ethernet pipe
(3) ENET_W - Sets the size of the eth_tx and eth_rx pipes.

eth_interface_tb runs traffic from e2c,e2v,v2e,c2e simultaneously
against the original xport_sv implementation, and against the new
implementation with widths of 64/128/512. A chdr_management node
info request queries the port info of the node0 in the eth_interface.

eth_ifc_synth_test.sv can be compiled with the make xsim target to test
out the size of various configurations.


Original-commit: eed4988cc266a63370a4332351d02fadedde3a3b
2020-06-30 10:29:35 -05:00

229 lines
7.1 KiB
Systemverilog

//
// Copyright 2020 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
// Module: eth_ipv4_interface
//
// Description:
// Adapts from internal CHDR to UDP/IPV4 Ethernet packets.
// Packets not specifically addressed to CHDR are routed
// to the CPU
//
// Parameters:
// - PROTOVER: RFNoC protocol version {8'd<major>, 8'd<minor>}
// - MTU: Log2 of the MTU of the packet in 64-bit words
// - CPU_FIFO_SIZE: Log2 of the FIFO depth (in 64-bit words) for the CPU egress path
// - RT_TBL_SIZE: Log2 of the depth of the return-address routing table
// - NODE_INST: The node type to return for a node-info discovery
// - DROP_UNKNOWN_MAC: Drop packets not addressed to us?
// - DROP_MIN_PACKET: Drop packets smaller than 64 bytes?
// - PREAMBLE_BYTES: Number of bytes of Preamble expected
// - ADD_SOF: Add a SOF indication into the tuser field
// - SYNC: Set if MAC is not the same as bus_clk
// - ENET_W: Width of the link to the Ethernet MAC
// - CPU_W: Width of the CPU interface
// - CHDR_W: Width of the CHDR interface
//
module eth_ipv4_interface #(
logic [15:0] PROTOVER = {8'd1, 8'd0},
int MTU = 10,
int CPU_FIFO_SIZE = MTU,
int NODE_INST = 0,
int RT_TBL_SIZE = 6,
int REG_AWIDTH = 14,
int BASE = 0,
bit DROP_UNKNOWN_MAC = 0,
bit DROP_MIN_PACKET = 0,
int PREAMBLE_BYTES = 6,
bit ADD_SOF = 1,
bit SYNC = 0,
int ENET_W = 64,
int CPU_W = 64,
int CHDR_W = 64
) (
input logic bus_clk,
input logic bus_rst,
input logic [15:0] device_id,
// Register port: Write port (domain: bus_clk)
input logic reg_wr_req,
input logic [REG_AWIDTH-1:0] reg_wr_addr,
input logic [31:0] reg_wr_data,
// Register port: Read port (domain: bus_clk)
input logic reg_rd_req,
input logic [REG_AWIDTH-1:0] reg_rd_addr,
output logic reg_rd_resp,
output logic [31:0] reg_rd_data,
// Status ports (domain: bus_clk)
output logic [47:0] my_mac,
output logic [31:0] my_ip,
output logic [15:0] my_udp_chdr_port,
// Ethernet MAC
AxiStreamIf.master eth_tx, // tUser = {1'b0,trailing bytes};
AxiStreamIf.slave eth_rx, // tUser = {error,trailing bytes};
// CHDR router interface
AxiStreamIf.master e2v, // tUser = {*not used*};
AxiStreamIf.slave v2e, // tUser = {*not used*};
// CPU DMA
AxiStreamIf.master e2c, // tUser = {sof,trailing bytes};
AxiStreamIf.slave c2e // tUser = {1'b0,trailing bytes};
);
localparam [47:0] DEFAULT_MAC_ADDR = {8'h00, 8'h80, 8'h2f, 8'h16, 8'hc5, 8'h2f};
localparam [31:0] DEFAULT_IP_ADDR = {8'd192, 8'd168, 8'd10, 8'd2};
localparam [31:0] DEFAULT_UDP_PORT = 16'd49153;
//---------------------------------------------------------
// Registers
//---------------------------------------------------------
// Include for register offsets
`include "eth_regs.vh"
// Allocate one full page for M
// mac_reg: MAC address for the dispatcher module. This value is used to
// determine if the packet is meant for this device and should be consumed.
//
// ip_reg: IP address for the dispatcher module. This value is used to
// determine if the packet is addressed to this device
//
// This module supports two destination ports.
logic [47:0] mac_reg = DEFAULT_MAC_ADDR;
logic [31:0] ip_reg = DEFAULT_IP_ADDR;
logic [15:0] udp_port = DEFAULT_UDP_PORT;
logic [47:0] bridge_mac_reg = DEFAULT_MAC_ADDR;
logic [31:0] bridge_ip_reg = DEFAULT_IP_ADDR;
logic [15:0] bridge_udp_port = DEFAULT_UDP_PORT;
logic bridge_en;
always_comb begin : bridge_mux
my_mac = bridge_en ? bridge_mac_reg : mac_reg;
my_ip = bridge_en ? bridge_ip_reg : ip_reg;
my_udp_chdr_port = bridge_en ? bridge_udp_port : udp_port;
end
always_ff @(posedge bus_clk) begin : reg_wr_ff
if (bus_rst) begin
mac_reg <= DEFAULT_MAC_ADDR;
ip_reg <= DEFAULT_IP_ADDR;
udp_port <= DEFAULT_UDP_PORT;
bridge_en <= 1'b0;
bridge_mac_reg <= DEFAULT_MAC_ADDR;
bridge_ip_reg <= DEFAULT_IP_ADDR;
bridge_udp_port <= DEFAULT_UDP_PORT;
end
else begin
if (reg_wr_req)
case (reg_wr_addr)
REG_MAC_LSB:
mac_reg[31:0] <= reg_wr_data;
REG_MAC_MSB:
mac_reg[47:32] <= reg_wr_data[15:0];
REG_IP:
ip_reg <= reg_wr_data;
REG_UDP:
udp_port <= reg_wr_data[15:0];
REG_BRIDGE_MAC_LSB:
bridge_mac_reg[31:0] <= reg_wr_data;
REG_BRIDGE_MAC_MSB:
bridge_mac_reg[47:32] <= reg_wr_data[15:0];
REG_BRIDGE_IP:
bridge_ip_reg <= reg_wr_data;
REG_BRIDGE_UDP:
bridge_udp_port <= reg_wr_data[15:0];
REG_BRIDGE_ENABLE:
bridge_en <= reg_wr_data[0];
endcase
end
end
always_ff @ (posedge bus_clk) begin : reg_rd_ff
if (bus_rst) begin
reg_rd_resp <= 1'b0;
reg_rd_data <= 32'd0;
end
else begin
if (reg_rd_req) begin
// Assert read response one cycle after read request
reg_rd_resp <= 1'b1;
case (reg_rd_addr)
REG_MAC_LSB:
reg_rd_data <= mac_reg[31:0];
REG_MAC_MSB:
reg_rd_data <= {16'b0,mac_reg[47:32]};
REG_IP:
reg_rd_data <= ip_reg;
REG_UDP:
reg_rd_data <= {16'b0, udp_port};
REG_BRIDGE_MAC_LSB:
reg_rd_data <= bridge_mac_reg[31:0];
REG_BRIDGE_MAC_MSB:
reg_rd_data <= {16'b0,bridge_mac_reg[47:32]};
REG_BRIDGE_IP:
reg_rd_data <= bridge_ip_reg;
REG_BRIDGE_UDP:
reg_rd_data <= {16'b0, bridge_udp_port};
REG_BRIDGE_ENABLE:
reg_rd_data <= {31'b0,bridge_en};
default:
reg_rd_resp <= 1'b0;
endcase
end
// Deassert read response after one clock cycle
if (reg_rd_resp) begin
reg_rd_resp <= 1'b0;
end
end
end
eth_ipv4_chdr_adapter #(
.PROTOVER (PROTOVER),
.MTU (MTU),
.CPU_FIFO_SIZE (CPU_FIFO_SIZE),
.RT_TBL_SIZE (RT_TBL_SIZE),
.NODE_INST (NODE_INST),
.DROP_UNKNOWN_MAC(DROP_UNKNOWN_MAC),
.DROP_MIN_PACKET (DROP_MIN_PACKET),
.PREAMBLE_BYTES (PREAMBLE_BYTES),
.ADD_SOF (ADD_SOF),
.SYNC (SYNC),
.ENET_W (ENET_W),
.CPU_W (CPU_W),
.CHDR_W (CHDR_W)
) eth_adapter_i (
.eth_rx (eth_rx ),
.eth_tx (eth_tx ),
.v2e (v2e ),
.e2v (e2v ),
.c2e (c2e ),
.e2c (e2c ),
.device_id (device_id),
.my_mac (my_mac ),
.my_ip (my_ip ),
.my_udp_chdr_port(my_udp_chdr_port )
);
endmodule : eth_ipv4_interface