From 4c75e48d248e0e4f143a66da5d1598e546eaf53a Mon Sep 17 00:00:00 2001 From: Wade Fife Date: Tue, 14 Sep 2021 17:12:15 -0500 Subject: fpga: lib: Clean up axi_mux --- fpga/usrp3/lib/fifo/axi_mux.v | 251 +++++++++++++++++++++++++++--------------- 1 file changed, 160 insertions(+), 91 deletions(-) diff --git a/fpga/usrp3/lib/fifo/axi_mux.v b/fpga/usrp3/lib/fifo/axi_mux.v index 72a771348..29727ad4b 100644 --- a/fpga/usrp3/lib/fifo/axi_mux.v +++ b/fpga/usrp3/lib/fifo/axi_mux.v @@ -1,110 +1,179 @@ - -// Copyright 2016 Ettus Research -// Copyright 2018 Ettus Research, a National Instruments Company +// +// Copyright 2021 Ettus Research, a National Instruments Brand // // SPDX-License-Identifier: LGPL-3.0-or-later +// +// Module: axi_mux +// +// Description: +// +// Takes arbitrary number of AXI streams and merges them to into a single +// output channel. Bubble cycles are inserted after each packet. +// +// Parameters: +// +// PRIO : Controls the arbitration scheme. +// 0 - Round-robin +// 1 - Priority (lower number ports get priority) +// WIDTH : Width of each AXI-Stream (width of TDATA). +// PRE_FIFO_SIZE : Log2 of the input buffer FIFO. Set to 0 for no FIFO. +// POST_FIFO_SIZE : Log2 of the output buffer FIFO. Set to 0 for no FIFO. +// SIZE : Number of input ports to the multiplexer. +// + +`default_nettype none -// axi_mux -- takes arbitrary number of AXI stream, merges them to 1 output channel -// Round-robin if PRIO=0, priority if PRIO=1 (lower number ports get priority) -// Bubble cycles are inserted after each packet -module axi_mux - #(parameter PRIO=0, - parameter WIDTH=64, - parameter PRE_FIFO_SIZE=0, - parameter POST_FIFO_SIZE=0, - parameter SIZE=4) - (input clk, input reset, input clear, - input [(WIDTH*SIZE)-1:0] i_tdata, input [SIZE-1:0] i_tlast, input [SIZE-1:0] i_tvalid, output [SIZE-1:0] i_tready, - output [WIDTH-1:0] o_tdata, output o_tlast, output o_tvalid, input o_tready); +module axi_mux #( + parameter PRIO = 0, + parameter WIDTH = 64, + parameter PRE_FIFO_SIZE = 0, + parameter POST_FIFO_SIZE = 0, + parameter SIZE = 4 +) ( + input wire clk, + input wire reset, + input wire clear, - wire [WIDTH*SIZE-1:0] i_tdata_int; - wire [SIZE-1:0] i_tlast_int, i_tvalid_int, i_tready_int; + // Input streams + input wire [WIDTH*SIZE-1:0] i_tdata, + input wire [ SIZE-1:0] i_tlast, + input wire [ SIZE-1:0] i_tvalid, + output wire [ SIZE-1:0] i_tready, - wire [WIDTH-1:0] o_tdata_int; - wire o_tlast_int, o_tvalid_int, o_tready_int; + // Single output stream + output wire [ WIDTH-1:0] o_tdata, + output wire o_tlast, + output wire o_tvalid, + input wire o_tready +); - reg [$clog2(SIZE)-1:0] st_port; - reg st_active; + wire [WIDTH*SIZE-1:0] i_tdata_int; + wire [ SIZE-1:0] i_tlast_int; + wire [ SIZE-1:0] i_tvalid_int; + wire [ SIZE-1:0] i_tready_int; + + wire [WIDTH-1:0] o_tdata_int; + wire o_tlast_int; + wire o_tvalid_int; + wire o_tready_int; + + reg [$clog2(SIZE)-1:0] st_port; + reg st_active; + + //--------------------------------------------------------------------------- + // Input FIFO + //--------------------------------------------------------------------------- genvar n; generate - if (PRE_FIFO_SIZE == 0) begin + if (PRE_FIFO_SIZE == 0) begin : gen_no_pre_fifo assign i_tdata_int = i_tdata; assign i_tlast_int = i_tlast; assign i_tvalid_int = i_tvalid; assign i_tready = i_tready_int; - end else begin + end else begin : gen_pre_fifo for (n = 0; n < SIZE; n = n + 1) begin - axi_fifo #(.WIDTH(WIDTH+1), .SIZE(PRE_FIFO_SIZE)) axi_fifo ( - .clk(clk), .reset(reset), .clear(clear), - .i_tdata({i_tlast[n],i_tdata[WIDTH*(n+1)-1:WIDTH*n]}), .i_tvalid(i_tvalid[n]), .i_tready(i_tready[n]), - .o_tdata({i_tlast_int[n],i_tdata_int[WIDTH*(n+1)-1:WIDTH*n]}), .o_tvalid(i_tvalid_int[n]), .o_tready(i_tready_int[n]), - .space(), .occupied()); + axi_fifo #( + .WIDTH(WIDTH+1 ), + .SIZE (PRE_FIFO_SIZE) + ) axi_fifo ( + .clk (clk ), + .reset (reset ), + .clear (clear ), + .i_tdata ({i_tlast[n],i_tdata[WIDTH*(n+1)-1:WIDTH*n]} ), + .i_tvalid(i_tvalid[n] ), + .i_tready(i_tready[n] ), + .o_tdata ({i_tlast_int[n],i_tdata_int[WIDTH*(n+1)-1:WIDTH*n]}), + .o_tvalid(i_tvalid_int[n] ), + .o_tready(i_tready_int[n] ), + .space ( ), + .occupied( ) + ); end end endgenerate - always @(posedge clk) - if(reset) - begin - st_port <= 0; - st_active <= 1'b0; - end - else - if(st_active) - begin - if(o_tlast_int & o_tvalid_int & o_tready_int) - begin - st_active <= 1'b0; - if((PRIO != 0) | (st_port == (SIZE-1))) - st_port <= 0; - else - st_port <= st_port + 1; - end - end // if (st_active) - else - if(i_tvalid_int[st_port]) - st_active <= 1'b1; - else - if(st_port == (SIZE-1)) - st_port <= 0; - else - st_port <= st_port + 1; - - genvar i; - generate - for(i=0;i