aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/axi_crossbar_regport.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control/axi_crossbar_regport.v')
-rw-r--r--fpga/usrp3/lib/control/axi_crossbar_regport.v193
1 files changed, 193 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/axi_crossbar_regport.v b/fpga/usrp3/lib/control/axi_crossbar_regport.v
new file mode 100644
index 000000000..15b74517d
--- /dev/null
+++ b/fpga/usrp3/lib/control/axi_crossbar_regport.v
@@ -0,0 +1,193 @@
+/////////////////////////////////////////////////////////////////////
+//
+// Copyright 2017 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: axi_crossbar_regport
+// Description:
+// - axi_crossbar with regport interface for register/CAM access
+//
+//////////////////////////////////////////////////////////////////////
+
+module axi_crossbar_regport #(
+ parameter REG_BASE = 0, // settings bus base address
+ 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 AXI4-STREAM buses
+ parameter NUM_OUTPUTS = 2, // number of output AXI4-STREAM buses
+ parameter REG_DWIDTH = 32, // Width of the AXI4-Lite data bus (must be 32 or 64)
+ parameter REG_AWIDTH = 14 // Width of the address bus
+)(
+ input clk,
+ input reset,
+ input clear,
+
+ input reg_wr_req,
+ input [REG_AWIDTH-1:0] reg_wr_addr,
+ input [REG_DWIDTH-1:0] reg_wr_data,
+
+ input reg_rd_req,
+ input [REG_AWIDTH-1:0] reg_rd_addr,
+ output [REG_DWIDTH-1:0] reg_rd_data,
+ output reg_rd_resp,
+
+ // 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,
+ input [NUM_INPUTS-1:0] pkt_present,
+
+ // Output
+ output [(FIFO_WIDTH*NUM_OUTPUTS)-1:0] o_tdata,
+ output [NUM_OUTPUTS-1:0] o_tvalid,
+ output [NUM_OUTPUTS-1:0] o_tlast,
+ input [NUM_OUTPUTS-1:0] o_tready
+);
+
+ localparam XBAR_VERSION = 32'b1;
+ localparam XBAR_NUM_PORTS = NUM_INPUTS; //or NUM_OUTPUTS
+
+ localparam REG_XBAR_VERSION = REG_BASE + 14'h10;
+ localparam REG_XBAR_NUM_PORTS = REG_BASE + 14'h14;
+ localparam REG_XBAR_LOCAL_ADDR = REG_BASE + 14'h18;
+ localparam REG_BASE_XBAR_SETTING_REG = REG_BASE + 14'h20;
+ localparam REG_END_ADDR_XBAR_SETTING_REG = REG_BASE + 14'h1000;
+
+ // Settings bus address width
+ localparam SR_AWIDTH = 12;
+
+ wire xbar_set_stb;
+ wire [REG_DWIDTH-1:0] xbar_set_data;
+ wire [SR_AWIDTH-1:0] xbar_set_addr;
+
+ wire xbar_rb_stb;
+ wire [SR_AWIDTH-1:0] xbar_rb_addr;
+ wire [REG_DWIDTH-1:0] xbar_rb_data;
+
+ reg [31:0] local_addr_reg;
+ reg reg_rd_resp_glob;
+ reg [REG_DWIDTH-1:0] reg_rd_data_glob;
+
+ wire [REG_DWIDTH-1:0] reg_rd_data_xbar;
+ wire reg_rd_resp_xbar;
+
+ regport_resp_mux #(
+ .WIDTH(REG_DWIDTH),
+ .NUM_SLAVES(2)
+ ) inst_regport_resp_mux_xbar (
+ .clk(clk),
+ .reset(reset),
+ .sla_rd_resp({reg_rd_resp_glob, reg_rd_resp_xbar}),
+ .sla_rd_data({reg_rd_data_glob, reg_rd_data_xbar}),
+ .mst_rd_resp(reg_rd_resp),
+ .mst_rd_data(reg_rd_data)
+ );
+
+ // Read Registers
+ always @ (posedge clk) begin
+ if (reset) begin
+ local_addr_reg <= 32'h0;
+ end
+ else begin
+ if (reg_wr_req)
+ case (reg_wr_addr)
+ REG_XBAR_LOCAL_ADDR:
+ local_addr_reg <= reg_wr_data;
+ endcase
+ end
+ end
+
+ // Write Registers
+ always @ (posedge clk) begin
+ if (reset)
+ reg_rd_resp_glob <= 1'b0;
+
+ else begin
+ if (reg_rd_req) begin
+ reg_rd_resp_glob <= 1'b1;
+
+ case (reg_rd_addr)
+ REG_XBAR_VERSION:
+ reg_rd_data_glob <= XBAR_VERSION;
+
+ REG_XBAR_NUM_PORTS:
+ reg_rd_data_glob <= XBAR_NUM_PORTS;
+
+ REG_XBAR_LOCAL_ADDR:
+ reg_rd_data_glob <= local_addr_reg;
+
+ default:
+ reg_rd_resp_glob <= 1'b0;
+ endcase
+ end
+ else if (reg_rd_resp_glob) begin
+ reg_rd_resp_glob <= 1'b0;
+ end
+ end
+ end
+
+ regport_to_xbar_settingsbus #(
+ .BASE(REG_BASE_XBAR_SETTING_REG),
+ .END_ADDR(REG_END_ADDR_XBAR_SETTING_REG),
+ .DWIDTH(REG_DWIDTH),
+ .AWIDTH(REG_AWIDTH),
+ .SR_AWIDTH(SR_AWIDTH),
+ .ADDRESSING("WORD")
+ ) inst_regport_to_xbar_settingsbus (
+ .clk(clk),
+ .reset(reset),
+
+ .reg_wr_req(reg_wr_req),
+ .reg_wr_addr(reg_wr_addr),
+ .reg_wr_data(reg_wr_data),
+ .reg_rd_req(reg_rd_req),
+ .reg_rd_addr(reg_rd_addr),
+ .reg_rd_data(reg_rd_data_xbar),
+ .reg_rd_resp(reg_rd_resp_xbar),
+
+ .set_stb(xbar_set_stb),
+ .set_addr(xbar_set_addr),
+ .set_data(xbar_set_data),
+ .rb_stb(xbar_rb_stb),
+ .rb_addr(xbar_rb_addr),
+ .rb_data(xbar_rb_data)
+ );
+
+ axi_crossbar #(
+ .BASE(0), // Set to 0 as logic for other values has not been tested
+ .FIFO_WIDTH(FIFO_WIDTH),
+ .DST_WIDTH(DST_WIDTH),
+ .NUM_INPUTS(NUM_INPUTS),
+ .NUM_OUTPUTS(NUM_OUTPUTS)
+ ) axi_crossbar (
+ .clk(clk),
+ .reset(reset),
+ .clear(1'b0),
+ .local_addr(local_addr_reg),
+
+ // settings bus for config
+ .set_stb(xbar_set_stb),
+ .set_addr({4'b0000,xbar_set_addr}),
+ .set_data(xbar_set_data),
+ .rb_rd_stb(xbar_rb_stb),
+ .rb_addr(xbar_rb_addr[$clog2(NUM_INPUTS)+$clog2(NUM_OUTPUTS)-1:0]),
+ .rb_data(xbar_rb_data),
+
+ // inputs, real men flatten busses
+ .i_tdata(i_tdata),
+ .i_tlast(i_tlast),
+ .i_tvalid(i_tvalid),
+ .i_tready(i_tready),
+
+ // outputs, real men flatten busses
+ .o_tdata(o_tdata),
+ .o_tlast(o_tlast),
+ .o_tvalid(o_tvalid),
+ .o_tready(o_tready),
+ .pkt_present(pkt_present)
+ );
+
+endmodule // axi_crossbar_regport
+