diff options
author | Wade Fife <wade.fife@ettus.com> | 2021-09-14 17:12:15 -0500 |
---|---|---|
committer | Wade Fife <wade.fife@ettus.com> | 2021-10-28 23:15:41 -0500 |
commit | 4c75e48d248e0e4f143a66da5d1598e546eaf53a (patch) | |
tree | 06bba5493b56f6f371a16c19e3f1d22e6d0b8683 /fpga | |
parent | e18c0ffbc4d1cbe1c0f083185212d57a6c201716 (diff) | |
download | uhd-4c75e48d248e0e4f143a66da5d1598e546eaf53a.tar.gz uhd-4c75e48d248e0e4f143a66da5d1598e546eaf53a.tar.bz2 uhd-4c75e48d248e0e4f143a66da5d1598e546eaf53a.zip |
fpga: lib: Clean up axi_mux
Diffstat (limited to 'fpga')
-rw-r--r-- | fpga/usrp3/lib/fifo/axi_mux.v | 251 |
1 files 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<SIZE;i=i+1) - begin : gen1 - assign i_tready_int[i] = st_active & o_tready_int & (st_port == i); - end - endgenerate - - assign o_tvalid_int = st_active & i_tvalid_int[st_port]; - assign o_tlast_int = i_tlast_int[st_port]; - - genvar j; - generate - for (j=0;j<WIDTH;j=j+1) - begin : gen2 - assign o_tdata_int[j] = i_tdata_int[st_port*WIDTH+j]; - end - endgenerate - - generate - if(POST_FIFO_SIZE == 0) - begin - assign o_tdata = o_tdata_int; - assign o_tlast = o_tlast_int; - assign o_tvalid = o_tvalid_int; - assign o_tready_int = o_tready; - end - else - axi_fifo #(.WIDTH(WIDTH+1),.SIZE(POST_FIFO_SIZE)) axi_fifo - (.clk(clk), .reset(reset), .clear(clear), - .i_tdata({o_tlast_int,o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int), - .o_tdata({o_tlast,o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready), - .space(), .occupied()); - endgenerate - -endmodule // axi__mux + //--------------------------------------------------------------------------- + // Multiplexer Logic + //--------------------------------------------------------------------------- + + always @(posedge clk) begin + if (reset) begin + st_port <= 0; + st_active <= 1'b0; + end else begin + 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))) begin + st_port <= 0; + end else begin + st_port <= st_port + 1; + end + end + end else begin + if (i_tvalid_int[st_port]) begin + st_active <= 1'b1; + end else begin + if (st_port == (SIZE-1)) begin + st_port <= 0; + end else begin + st_port <= st_port + 1; + end + end + end + end + end + + genvar i; + generate + for (i=0; i<SIZE; i=i+1) begin : gen_tready + assign i_tready_int[i] = st_active & o_tready_int & (st_port == i); + end + endgenerate + + assign o_tvalid_int = st_active & i_tvalid_int[st_port]; + assign o_tlast_int = i_tlast_int[st_port]; + + genvar j; + generate + for (j=0; j<WIDTH; j=j+1) begin : gen_tdata + assign o_tdata_int[j] = i_tdata_int[st_port*WIDTH+j]; + end + endgenerate + + //--------------------------------------------------------------------------- + // Output FIFO + //--------------------------------------------------------------------------- + + generate + if (POST_FIFO_SIZE == 0) begin + assign o_tdata = o_tdata_int; + assign o_tlast = o_tlast_int; + assign o_tvalid = o_tvalid_int; + assign o_tready_int = o_tready; + end else begin + axi_fifo #( + .WIDTH(WIDTH+1 ), + .SIZE (POST_FIFO_SIZE) + ) axi_fifo ( + .clk (clk ), + .reset (reset ), + .clear (clear ), + .i_tdata ({o_tlast_int,o_tdata_int}), + .i_tvalid(o_tvalid_int ), + .i_tready(o_tready_int ), + .o_tdata ({o_tlast,o_tdata} ), + .o_tvalid(o_tvalid ), + .o_tready(o_tready ), + .space ( ), + .occupied( ) + ); + end + endgenerate + +endmodule + + +`default_nettype wire |