aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/rfnoc/crossbar/axis_ingress_vc_buff.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/rfnoc/crossbar/axis_ingress_vc_buff.v')
-rw-r--r--fpga/usrp3/lib/rfnoc/crossbar/axis_ingress_vc_buff.v178
1 files changed, 178 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/rfnoc/crossbar/axis_ingress_vc_buff.v b/fpga/usrp3/lib/rfnoc/crossbar/axis_ingress_vc_buff.v
new file mode 100644
index 000000000..fd10d6682
--- /dev/null
+++ b/fpga/usrp3/lib/rfnoc/crossbar/axis_ingress_vc_buff.v
@@ -0,0 +1,178 @@
+//
+// Copyright 2018 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: axis_ingress_vc_buff
+// Description:
+// A wrapper around a buffer to implement one or more virtual channels
+// Supports gate a packet for cut-through routing
+
+module axis_ingress_vc_buff #(
+ parameter WIDTH = 64, // Width of the datapath
+ parameter NUM_VCS = 2, // Number of virtual channels
+ parameter SIZE = 5, // Virtual channel buffer size
+ parameter ROUTING = "WORMHOLE", // Routing (switching) method {WORMHOLE, CUT-THROUGH}
+ parameter DEST_W = (NUM_VCS > 1) ? $clog2(NUM_VCS) : 1 // PRIVATE
+) (
+ input wire clk,
+ input wire reset,
+ input wire [WIDTH-1:0] s_axis_tdata,
+ input wire [DEST_W-1:0] s_axis_tdest,
+ input wire s_axis_tlast,
+ input wire s_axis_tvalid,
+ output wire s_axis_tready,
+ output wire [WIDTH-1:0] m_axis_tdata,
+ output wire m_axis_tlast,
+ output wire m_axis_tvalid,
+ input wire m_axis_tready
+);
+
+ generate if (NUM_VCS > 1) begin
+ //----------------------------------------------------
+ // Multiple virtual channels
+ //----------------------------------------------------
+
+ wire [(WIDTH*NUM_VCS)-1:0] bufin_tdata , bufout_tdata ;
+ wire [NUM_VCS-1:0] bufin_tlast , bufout_tlast ;
+ wire [NUM_VCS-1:0] bufin_tvalid, bufout_tvalid;
+ wire [NUM_VCS-1:0] bufin_tready, bufout_tready;
+
+ axi_demux #(
+ .WIDTH(WIDTH), .SIZE(NUM_VCS),
+ .PRE_FIFO_SIZE(0 /* must be 0 */), .POST_FIFO_SIZE(0)
+ ) vc_demux_i (
+ .clk (clk),
+ .reset (reset),
+ .clear (1'b0),
+ .header (/* unused */),
+ .dest (s_axis_tdest ),
+ .i_tdata (s_axis_tdata ),
+ .i_tlast (s_axis_tlast ),
+ .i_tvalid (s_axis_tvalid),
+ .i_tready (s_axis_tready),
+ .o_tdata (bufin_tdata),
+ .o_tlast (bufin_tlast),
+ .o_tvalid (bufin_tvalid),
+ .o_tready (bufin_tready)
+ );
+
+ genvar vc;
+ for (vc = 0; vc < NUM_VCS; vc = vc + 1) begin
+ if (ROUTING == "WORMHOLE") begin
+ axi_fifo #(
+ .WIDTH(WIDTH+1), .SIZE(SIZE)
+ ) buf_i (
+ .clk (clk),
+ .reset (reset),
+ .clear (1'b0),
+ .i_tdata ({bufin_tlast[vc], bufin_tdata [(vc*WIDTH)+:WIDTH]}),
+ .i_tvalid (bufin_tvalid [vc]),
+ .i_tready (bufin_tready [vc]),
+ .o_tdata ({bufout_tlast[vc], bufout_tdata [(vc*WIDTH)+:WIDTH]}),
+ .o_tvalid (bufout_tvalid[vc]),
+ .o_tready (bufout_tready[vc]),
+ .space (),
+ .occupied ()
+ );
+ end else begin
+ axi_packet_gate #(
+ .WIDTH(WIDTH), .SIZE(SIZE)
+ ) buf_i (
+ .clk (clk),
+ .reset (reset),
+ .clear (1'b0),
+ .i_tdata (bufin_tdata[(vc*WIDTH)+:WIDTH]),
+ .i_tlast (bufin_tlast[vc]),
+ .i_tvalid (bufin_tvalid[vc]),
+ .i_tready (bufin_tready[vc]),
+ .i_terror (1'b0),
+ .o_tdata (bufout_tdata[(vc*WIDTH)+:WIDTH]),
+ .o_tlast (bufout_tlast[vc]),
+ .o_tvalid (bufout_tvalid[vc]),
+ .o_tready (bufout_tready[vc])
+ );
+ end
+ end
+
+ axi_mux #(
+ .WIDTH(WIDTH), .SIZE(NUM_VCS),
+ .PRE_FIFO_SIZE(0), .POST_FIFO_SIZE(1)
+ ) vc_mux_i (
+ .clk (clk),
+ .reset (reset),
+ .clear (1'b0),
+ .i_tdata (bufout_tdata ),
+ .i_tlast (bufout_tlast ),
+ .i_tvalid (bufout_tvalid),
+ .i_tready (bufout_tready),
+ .o_tdata (m_axis_tdata ),
+ .o_tlast (m_axis_tlast ),
+ .o_tvalid (m_axis_tvalid),
+ .o_tready (m_axis_tready)
+ );
+
+ end else begin
+ //----------------------------------------------------
+ // Single virtual channel
+ //----------------------------------------------------
+ wire [WIDTH-1:0] pipe_tdata;
+ wire pipe_tlast;
+ wire pipe_tvalid;
+ wire pipe_tready;
+
+ if (ROUTING == "WORMHOLE") begin
+ axi_fifo #(
+ .WIDTH(WIDTH+1), .SIZE(SIZE)
+ ) buf_i (
+ .clk (clk),
+ .reset (reset),
+ .clear (1'b0),
+ .i_tdata ({s_axis_tlast, s_axis_tdata}),
+ .i_tvalid (s_axis_tvalid ),
+ .i_tready (s_axis_tready ),
+ .o_tdata ({pipe_tlast, pipe_tdata}),
+ .o_tvalid (pipe_tvalid),
+ .o_tready (pipe_tready),
+ .space (),
+ .occupied ()
+ );
+ end else begin
+ axi_packet_gate #(
+ .WIDTH(WIDTH), .SIZE(SIZE)
+ ) buf_i (
+ .clk (clk),
+ .reset (reset),
+ .clear (1'b0),
+ .i_tdata (s_axis_tdata),
+ .i_tlast (s_axis_tlast),
+ .i_tvalid (s_axis_tvalid),
+ .i_tready (s_axis_tready),
+ .i_terror (1'b0),
+ .o_tdata (pipe_tdata),
+ .o_tlast (pipe_tlast),
+ .o_tvalid (pipe_tvalid),
+ .o_tready (pipe_tready)
+ );
+ end
+
+ axi_fifo #(
+ .WIDTH(WIDTH+1), .SIZE(1)
+ ) buf_i (
+ .clk (clk),
+ .reset (reset),
+ .clear (1'b0),
+ .i_tdata ({pipe_tlast, pipe_tdata}),
+ .i_tvalid (pipe_tvalid ),
+ .i_tready (pipe_tready ),
+ .o_tdata ({m_axis_tlast, m_axis_tdata}),
+ .o_tvalid (m_axis_tvalid),
+ .o_tready (m_axis_tready),
+ .space (),
+ .occupied ()
+ );
+
+ end endgenerate
+
+endmodule
+