aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/axi_slave_mux.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control/axi_slave_mux.v')
-rw-r--r--fpga/usrp3/lib/control/axi_slave_mux.v122
1 files changed, 122 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/axi_slave_mux.v b/fpga/usrp3/lib/control/axi_slave_mux.v
new file mode 100644
index 000000000..1a307aba5
--- /dev/null
+++ b/fpga/usrp3/lib/control/axi_slave_mux.v
@@ -0,0 +1,122 @@
+//
+// Copyright 2012 Ettus Research LLC
+//
+
+
+
+
+`define LOG2(N) (\
+ N < 2 ? 0 : \
+ N < 4 ? 1 : \
+ N < 8 ? 2 : \
+ N < 16 ? 3 : \
+ N < 32 ? 4 : \
+ N < 64 ? 5 : \
+ N < 128 ? 6 : \
+ N < 256 ? 7 : \
+ N < 512 ? 8 : \
+ N < 1024 ? 9 : \
+ 10)
+
+
+module axi_slave_mux
+ #(
+ parameter FIFO_WIDTH = 64, // AXI4-STREAM data bus width
+ parameter DST_WIDTH = 16, // Width of DST field we are routing on.
+ parameter NUM_INPUTS = 2 // number of input AXI buses
+ )
+ (
+ input clk,
+ input reset,
+ input clear,
+ // Inputs
+ input [(FIFO_WIDTH*NUM_INPUTS)-1:0] i_tdata,
+ input [NUM_INPUTS-1:0] i_tvalid,
+ input [NUM_INPUTS-1:0] i_tlast,
+ output [NUM_INPUTS-1:0] i_tready,
+ // Forwarding Flags
+ input [NUM_INPUTS-1:0] forward_valid,
+ output reg [NUM_INPUTS-1:0] forward_ack,
+ // Output
+ output [FIFO_WIDTH-1:0] o_tdata,
+ output o_tvalid,
+ output o_tlast,
+ input o_tready
+ );
+
+ wire [FIFO_WIDTH-1:0] i_tdata_array [0:NUM_INPUTS-1];
+
+ reg [`LOG2(NUM_INPUTS):0] select;
+ reg enable;
+
+
+ reg state;
+
+ localparam CHECK_THIS_INPUT = 0;
+ localparam WAIT_LAST = 1;
+
+
+ always @(posedge clk)
+ if (reset | clear) begin
+ state <= CHECK_THIS_INPUT;
+ select <= 0;
+ enable <= 0;
+ forward_ack <= 0;
+ end else begin
+ case(state)
+ // Is the currently selected input addressing this slave with a ready packet?
+ CHECK_THIS_INPUT: begin
+ if (forward_valid[select]) begin
+ enable <= 1;
+ forward_ack[select] <= 1;
+ state <= WAIT_LAST;
+ end else if (select == NUM_INPUTS - 1 ) begin
+ select <= 0;
+ end else begin
+ select <= select + 1;
+ end
+ end
+ // Assert ACK immediately to forwarding logic and then wait for end of packet.
+ WAIT_LAST: begin
+
+ if (i_tlast[select] && i_tvalid[select] && o_tready) begin
+ if (select == NUM_INPUTS - 1 ) begin
+ select <= 0;
+ end else begin
+ select <= select + 1;
+ end
+ state <= CHECK_THIS_INPUT;
+ forward_ack <= 0;
+ enable <= 0;
+ end else begin
+ forward_ack[select] <= 1;
+ enable <= 1;
+ end
+ end
+ endcase // case(state)
+ end
+
+ //
+ // Combinatorial mux
+ //
+ genvar m;
+
+ generate
+ for (m = 0; m < NUM_INPUTS; m = m + 1) begin: form_buses
+ assign i_tdata_array[m] = i_tdata[(m*FIFO_WIDTH)+FIFO_WIDTH-1:m*FIFO_WIDTH];
+ end
+ endgenerate
+
+ assign o_tdata = i_tdata_array[select];
+ assign o_tvalid = enable && i_tvalid[select];
+ assign o_tlast = enable && i_tlast[select];
+ // assign i_tready = {NUM_INPUTS{o_tready}} & (enable << select);
+
+ generate
+ for (m = 0; m < NUM_INPUTS; m = m + 1) begin: form_ready
+ assign i_tready[m] = o_tready && enable && (select == m);
+ end
+ endgenerate
+
+
+endmodule // axi_slave_mux