aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/regport_to_xbar_settingsbus.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control/regport_to_xbar_settingsbus.v')
-rw-r--r--fpga/usrp3/lib/control/regport_to_xbar_settingsbus.v113
1 files changed, 113 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/regport_to_xbar_settingsbus.v b/fpga/usrp3/lib/control/regport_to_xbar_settingsbus.v
new file mode 100644
index 000000000..be050dd20
--- /dev/null
+++ b/fpga/usrp3/lib/control/regport_to_xbar_settingsbus.v
@@ -0,0 +1,113 @@
+/////////////////////////////////////////////////////////////////////
+//
+// Copyright 2017 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: regport_to_xbar_settingsbus
+// Description:
+// Converts regport to xbar setting bus.
+// The module is designed only for the crossbar. The readback bus for the
+// rfnoc crossbar reads from the same address as it writes to. Also
+// there is an extra cycle delay in read data in the crossbar, which is
+// why the rb_stb needs to be delayed by a cycle.
+//
+// ADDRESSING: Set to "WORD" in case of settings bus. The settings bus
+// uses word addressing and hence the address needs to be shifted by
+// to convert to set_addr.
+//
+/////////////////////////////////////////////////////////////////////
+
+module regport_to_xbar_settingsbus #(
+ parameter BASE = 14'h0,
+ parameter END_ADDR = 14'h3FFF,
+ parameter DWIDTH = 32,
+ parameter AWIDTH = 14,
+ parameter SR_AWIDTH = 12,
+ // Dealign for settings bus by shifting by 2
+ parameter ADDRESSING = "WORD",
+ parameter SHIFT = $clog2(DWIDTH/8)
+ )(
+ input clk,
+ input reset,
+
+ input reg_wr_req,
+ input [AWIDTH-1:0] reg_wr_addr,
+ input [DWIDTH-1:0] reg_wr_data,
+
+ input reg_rd_req,
+ input [AWIDTH-1:0] reg_rd_addr,
+ output [DWIDTH-1:0] reg_rd_data,
+ output reg_rd_resp,
+
+ output set_stb,
+ output [SR_AWIDTH-1:0] set_addr,
+ output [DWIDTH-1:0] set_data,
+
+ output rb_stb,
+ output [SR_AWIDTH-1:0] rb_addr,
+ input [DWIDTH-1:0] rb_data
+);
+
+ reg reg_rd_req_delay;
+ reg reg_rd_req_delay2;
+ wire [AWIDTH-1:0] set_addr_int;
+ reg [AWIDTH-1:0] rb_addr_int;
+
+ always @(posedge clk) begin
+ if (reset) begin
+ reg_rd_req_delay <= 1'b0;
+ reg_rd_req_delay2 <= 1'b0;
+ rb_addr_int <= 'd0;
+ end
+ else if (reg_rd_req) begin
+ rb_addr_int <= reg_rd_addr - BASE;
+ reg_rd_req_delay <= 1'b1;
+ end
+ else if (reg_rd_req_delay) begin
+ reg_rd_req_delay2 <= 1'b1;
+ reg_rd_req_delay <= 1'b0;
+ end
+ // Deassert after two clock cycles
+ else if (reg_rd_req_delay2) begin
+ reg_rd_req_delay <= 1'b0;
+ reg_rd_req_delay2 <= 1'b0;
+ rb_addr_int <= 'd0;
+ end
+ else begin
+ reg_rd_req_delay <= 1'b0;
+ reg_rd_req_delay2 <= 1'b0;
+ rb_addr_int <= 'd0;
+ end
+ end
+
+ // Write mode of settings bus
+ regport_to_settingsbus #(
+ .BASE(BASE),
+ .END_ADDR(END_ADDR),
+ .DWIDTH(DWIDTH),
+ .AWIDTH(AWIDTH),
+ .SR_AWIDTH(SR_AWIDTH),
+ .ADDRESSING(ADDRESSING)
+ ) xbar_write_settings_bus (
+ .clk(clk),
+ .reset(reset),
+ .reg_wr_req(reg_wr_req),
+ .reg_wr_addr(reg_wr_addr),
+ .reg_wr_data(reg_wr_data),
+
+ .set_stb(set_stb),
+ .set_addr(set_addr),
+ .set_data(set_data)
+ );
+
+ assign rb_addr = (ADDRESSING == "WORD") ? {{SHIFT{1'b0}}, rb_addr_int[SR_AWIDTH-1:SHIFT]}
+ : rb_addr_int[SR_AWIDTH-1:0];
+ // Strobe asserted two cycle after read request only when address is between BASE and END ADDR
+ // This is specific to the xbar as the xbar delays read data by an extra clock
+ // cycle to relax timing.
+ assign rb_stb = reg_rd_req_delay2 && (reg_rd_addr >= BASE) && (reg_rd_addr <= END_ADDR);
+ assign reg_rd_resp = rb_stb;
+ assign reg_rd_data = rb_data;
+
+endmodule