Files
b210-k7-fpga/lib/rfnoc/xport/eth_interface.v
T
Wade Fife 20340f7054 fpga: lib: Add compat to Verilog transport adapter
Original-commit: e716c8c720718f69d39823b722f5e013df99a3d5
2022-08-29 17:01:45 -05:00

250 lines
7.0 KiB
Verilog

//
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
// Adapts from internal VITA to ethernet packets. Also handles CPU and ethernet crossover interfaces.
module eth_interface #(
parameter [15:0] PROTOVER = {8'd1, 8'd0},
parameter MTU = 10,
parameter NODE_INST = 0,
parameter RT_TBL_SIZE = 6,
parameter REG_AWIDTH = 14,
parameter BASE = 0
) (
input clk,
input reset,
input [15:0] device_id,
// Register port: Write port (domain: clk)
input reg_wr_req,
input [REG_AWIDTH-1:0] reg_wr_addr,
input [31:0] reg_wr_data,
// Register port: Read port (domain: clk)
input reg_rd_req,
input [REG_AWIDTH-1:0] reg_rd_addr,
output reg reg_rd_resp,
output reg [31:0] reg_rd_data,
// Status ports (domain: clk)
output [47:0] my_mac,
output [31:0] my_ip,
output [15:0] my_udp_port,
// Ethernet ports
output [63:0] eth_tx_tdata,
output [3:0] eth_tx_tuser,
output eth_tx_tlast,
output eth_tx_tvalid,
input eth_tx_tready,
input [63:0] eth_rx_tdata,
input [3:0] eth_rx_tuser,
input eth_rx_tlast,
input eth_rx_tvalid,
output eth_rx_tready,
// 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 [3:0] e2c_tuser,
output e2c_tlast,
output e2c_tvalid,
input e2c_tready,
input [63:0] c2e_tdata,
input [3:0] c2e_tuser,
input c2e_tlast,
input c2e_tvalid,
output c2e_tready
);
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 "../xport_sv/eth_regs.vh"
// MAC address for the dispatcher module.
// This value is used to determine if the packet is meant
// for this device should be consumed
// 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
reg [47:0] mac_reg;
reg [31:0] ip_reg;
reg [15:0] udp_port;
reg [47:0] bridge_mac_reg;
reg [31:0] bridge_ip_reg;
reg [15:0] bridge_udp_port;
reg bridge_en;
assign my_mac = bridge_en ? bridge_mac_reg : mac_reg;
assign my_ip = bridge_en ? bridge_ip_reg : ip_reg;
assign my_udp_port = bridge_en ? bridge_udp_port : udp_port;
always @(posedge clk) begin
if (reset) 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 @ (posedge clk) begin
// No reset handling required for readback
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};
REG_XPORT_COMPAT:
// Return compat of 0 to indicate this is the old transport adapter
reg_rd_data <= 32'b0;
REG_XPORT_INFO:
// This TA has no advanced capabilities (e.g., raw UDP)
reg_rd_data <= 32'b0;
REG_XPORT_NODE_INST:
reg_rd_data <= NODE_INST;
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
// 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_switch is the number of valid bytes
eth_ipv4_chdr64_adapter #(
.PROTOVER (PROTOVER),
.MTU (MTU),
.CPU_FIFO_SIZE (MTU),
.RT_TBL_SIZE (RT_TBL_SIZE),
.NODE_INST (NODE_INST),
.DROP_UNKNOWN_MAC(0),
.IS_CPU_ARM (1)
) eth_adapter_i (
.clk (clk ),
.rst (reset ),
.device_id (device_id ),
.s_mac_tdata (eth_rx_tdata ),
.s_mac_tuser (eth_rx_tuser ),
.s_mac_tlast (eth_rx_tlast ),
.s_mac_tvalid (eth_rx_tvalid),
.s_mac_tready (eth_rx_tready),
.m_mac_tdata (eth_tx_tdata ),
.m_mac_tuser (eth_tx_tuser ),
.m_mac_tlast (eth_tx_tlast ),
.m_mac_tvalid (eth_tx_tvalid),
.m_mac_tready (eth_tx_tready),
.s_chdr_tdata (v2e_tdata ),
.s_chdr_tlast (v2e_tlast ),
.s_chdr_tvalid (v2e_tvalid ),
.s_chdr_tready (v2e_tready ),
.m_chdr_tdata (e2v_tdata ),
.m_chdr_tlast (e2v_tlast ),
.m_chdr_tvalid (e2v_tvalid ),
.m_chdr_tready (e2v_tready ),
.s_cpu_tdata (c2e_tdata ),
.s_cpu_tuser (c2e_tuser ),
.s_cpu_tlast (c2e_tlast ),
.s_cpu_tvalid (c2e_tvalid ),
.s_cpu_tready (c2e_tready ),
.m_cpu_tdata (e2c_tdata ),
.m_cpu_tuser (e2c_tuser ),
.m_cpu_tlast (e2c_tlast ),
.m_cpu_tvalid (e2c_tvalid ),
.m_cpu_tready (e2c_tready ),
.my_eth_addr (my_mac ),
.my_ipv4_addr (my_ip ),
.my_udp_chdr_port(my_udp_port )
);
endmodule // eth_interface