diff options
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.v | 178 |
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 + |