aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/rfnoc/crossbar/chdr_xb_routing_table.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/rfnoc/crossbar/chdr_xb_routing_table.v')
-rw-r--r--fpga/usrp3/lib/rfnoc/crossbar/chdr_xb_routing_table.v122
1 files changed, 122 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/rfnoc/crossbar/chdr_xb_routing_table.v b/fpga/usrp3/lib/rfnoc/crossbar/chdr_xb_routing_table.v
new file mode 100644
index 000000000..f445efc68
--- /dev/null
+++ b/fpga/usrp3/lib/rfnoc/crossbar/chdr_xb_routing_table.v
@@ -0,0 +1,122 @@
+//
+// Copyright 2018 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: chdr_xb_routing_table
+// Description:
+// A routing table for the CHDR crossbar. This table is designed
+// to be shared between all ports. It has an AXI-Stream lookup
+// interface and a ctrlport (reduced) configuration interface.
+
+module chdr_xb_routing_table #(
+ parameter SIZE = 6,
+ parameter NPORTS = 4,
+ parameter EXT_INS_PORT_EN = 1
+) (
+ // Clocks and resets
+ input wire clk,
+ input wire reset,
+ // Insertion Interface (for XB ports)
+ input wire [NPORTS-1:0] port_req_wr,
+ input wire [(16*NPORTS)-1:0] port_req_addr,
+ input wire [(32*NPORTS)-1:0] port_req_data,
+ output wire [NPORTS-1:0] port_resp_ack,
+ // Insertion Interface (External)
+ input wire ext_req_wr,
+ input wire [15:0] ext_req_addr,
+ input wire [31:0] ext_req_data,
+ output wire ext_resp_ack,
+ // Find Interface
+ input wire [(16*NPORTS)-1:0] axis_find_tdata,
+ input wire [NPORTS-1:0] axis_find_tvalid,
+ output wire [NPORTS-1:0] axis_find_tready,
+ // Result Interface (for Find)
+ output wire [($clog2(NPORTS)*NPORTS)-1:0] axis_result_tdata,
+ output wire [NPORTS-1:0] axis_result_tkeep,
+ output wire [NPORTS-1:0] axis_result_tvalid,
+ input wire [NPORTS-1:0] axis_result_tready
+);
+ localparam NPORTS_W = $clog2(NPORTS);
+ localparam CFG_W = NPORTS_W + 16;
+ localparam CFG_PORTS = NPORTS + EXT_INS_PORT_EN;
+
+ // CAM-based lookup table
+
+ wire [15:0] insert_tdest;
+ wire [NPORTS_W-1:0] insert_tdata;
+ wire insert_tvalid;
+ wire insert_tready;
+
+ axis_muxed_kv_map #(
+ .KEY_WIDTH(16), .VAL_WIDTH(NPORTS_W),
+ .SIZE(SIZE), .NUM_PORTS(NPORTS)
+ ) kv_map_i (
+ .clk (clk ),
+ .reset (reset ),
+ .axis_insert_tdata (insert_tdata ),
+ .axis_insert_tdest (insert_tdest ),
+ .axis_insert_tvalid(insert_tvalid ),
+ .axis_insert_tready(insert_tready ),
+ .axis_find_tdata (axis_find_tdata ),
+ .axis_find_tvalid (axis_find_tvalid ),
+ .axis_find_tready (axis_find_tready ),
+ .axis_result_tdata (axis_result_tdata ),
+ .axis_result_tkeep (axis_result_tkeep ),
+ .axis_result_tvalid(axis_result_tvalid),
+ .axis_result_tready(axis_result_tready)
+ );
+
+ // Logic to convert from ctrlport to AXI-Stream
+
+ wire ins_req_wr [0:CFG_PORTS-1];
+ wire [15:0] ins_req_addr[0:CFG_PORTS-1];
+ wire [NPORTS_W-1:0] ins_req_data[0:CFG_PORTS-1];
+ wire ins_resp_ack[0:CFG_PORTS-1];
+
+ reg [(CFG_PORTS*CFG_W)-1:0] cfg_tdata;
+ reg [CFG_PORTS-1:0] cfg_tvalid = {CFG_PORTS{1'b0}};
+ wire [CFG_PORTS-1:0] cfg_tready;
+
+ genvar i;
+ generate for (i = 0; i < CFG_PORTS; i=i+1) begin
+ assign ins_req_wr [i] = (i < NPORTS) ? port_req_wr[i] : ext_req_wr;
+ assign ins_req_addr[i] = (i < NPORTS) ? port_req_addr[i*16 +: 16] : ext_req_addr;
+ assign ins_req_data[i] = (i < NPORTS) ? port_req_data[i*32 +: NPORTS_W] : ext_req_data[NPORTS_W-1:0];
+ if (i < NPORTS)
+ assign port_resp_ack[i] = ins_resp_ack[i];
+ else
+ assign ext_resp_ack = ins_resp_ack[i];
+
+ always @(posedge clk) begin
+ if (reset) begin
+ cfg_tvalid[i] <= 1'b0;
+ end else begin
+ if (~cfg_tvalid[i]) begin
+ if (ins_req_wr[i]) begin
+ cfg_tvalid[i] <= 1'b1;
+ cfg_tdata[(CFG_W*i) +: CFG_W] <= {ins_req_data[i], ins_req_addr[i]};
+ end
+ end else begin
+ cfg_tvalid[i] <= ~cfg_tready[i];
+ end
+ end
+ end
+ assign ins_resp_ack[i] = cfg_tvalid[i] & cfg_tready[i];
+ end endgenerate
+
+ // Multiplexer between XB ports and external cfg
+
+ axi_mux #(
+ .WIDTH(CFG_W), .SIZE(CFG_PORTS),
+ .PRE_FIFO_SIZE(0), .POST_FIFO_SIZE(1)
+ ) rtcfg_mux_i (
+ .clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata(cfg_tdata), .i_tlast({(NPORTS_W + 16){1'b1}}),
+ .i_tvalid(cfg_tvalid), .i_tready(cfg_tready),
+ .o_tdata({insert_tdata, insert_tdest}), .o_tlast(),
+ .o_tvalid(insert_tvalid), .o_tready(insert_tready)
+ );
+
+endmodule
+