aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/rfnoc/xport/eth_interface.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/rfnoc/xport/eth_interface.v')
-rw-r--r--fpga/usrp3/lib/rfnoc/xport/eth_interface.v252
1 files changed, 252 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/rfnoc/xport/eth_interface.v b/fpga/usrp3/lib/rfnoc/xport/eth_interface.v
new file mode 100644
index 000000000..21e8b809d
--- /dev/null
+++ b/fpga/usrp3/lib/rfnoc/xport/eth_interface.v
@@ -0,0 +1,252 @@
+//
+// 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
+ //---------------------------------------------------------
+
+ // Allocate one full page for MAC
+ localparam [REG_AWIDTH-1:0] REG_MAC_LSB = BASE + 'h0000;
+ localparam [REG_AWIDTH-1:0] REG_MAC_MSB = BASE + 'h0004;
+
+ // Source IP address
+ localparam [REG_AWIDTH-1:0] REG_IP = BASE + 'h1000;
+ // Source UDP Port
+ localparam [REG_AWIDTH-1:0] REG_UDP = BASE + 'h1004;
+
+ // Registers for Internal/Bridge Network Mode in CPU
+ localparam [REG_AWIDTH-1:0] REG_BRIDGE_MAC_LSB = BASE + 'h1010;
+ localparam [REG_AWIDTH-1:0] REG_BRIDGE_MAC_MSB = BASE + 'h1014;
+ localparam [REG_AWIDTH-1:0] REG_BRIDGE_IP = BASE + 'h1018;
+ localparam [REG_AWIDTH-1:0] REG_BRIDGE_UDP = BASE + 'h101c;
+ localparam [REG_AWIDTH-1:0] REG_BRIDGE_ENABLE = BASE + 'h1020;
+
+ // 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};
+
+ 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 numbier 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