aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/axil_to_ni_regport.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control/axil_to_ni_regport.v')
-rw-r--r--fpga/usrp3/lib/control/axil_to_ni_regport.v164
1 files changed, 164 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/axil_to_ni_regport.v b/fpga/usrp3/lib/control/axil_to_ni_regport.v
new file mode 100644
index 000000000..876991ed9
--- /dev/null
+++ b/fpga/usrp3/lib/control/axil_to_ni_regport.v
@@ -0,0 +1,164 @@
+//
+// Copyright 2016 Ettus Research
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// AXI4lite to NI Register Port interface
+//
+
+module axil_to_ni_regport #(
+ parameter RP_AWIDTH = 16,
+ parameter RP_DWIDTH = 32,
+ parameter TIMEOUT = 512
+)(
+ input s_axi_aclk,
+ input s_axi_areset,
+
+ // AXI4lite interface
+ input [31:0] s_axi_awaddr,
+ input s_axi_awvalid,
+ output s_axi_awready,
+ input [31:0] s_axi_wdata,
+ input [3:0] s_axi_wstrb,
+ input s_axi_wvalid,
+ output s_axi_wready,
+ output [1:0] s_axi_bresp,
+ output s_axi_bvalid,
+ input s_axi_bready,
+ input [31:0] s_axi_araddr,
+ input s_axi_arvalid,
+ output s_axi_arready,
+ output [31:0] s_axi_rdata,
+ output [1:0] s_axi_rresp,
+ output s_axi_rvalid,
+ input s_axi_rready,
+
+ // RegPort interface, the out vs in
+ // is seen from the slave device
+ // hooked up to the regport
+ output reg_port_in_rd,
+ output reg_port_in_wt,
+ output [RP_AWIDTH-1:0] reg_port_in_addr,
+ output [RP_DWIDTH-1:0] reg_port_in_data,
+ input [RP_DWIDTH-1:0] reg_port_out_data,
+ input reg_port_out_ready
+);
+
+ localparam IDLE = 3'd0;
+ localparam READ_INIT = 3'd1;
+ localparam WRITE_INIT = 3'd2;
+ localparam READ_IN_PROGRESS = 3'd3;
+ localparam WRITE_IN_PROGRESS = 3'd4;
+ localparam WRITE_DONE = 3'd5;
+ localparam READ_DONE = 3'd6;
+
+ reg [RP_AWIDTH-1:0] addr;
+ reg [RP_DWIDTH-1:0] rb_data;
+ reg [RP_DWIDTH-1:0] wr_data;
+ reg [2:0] state;
+ reg [9:0] count;
+ reg [1:0] rresp;
+ reg [1:0] bresp;
+
+ always @ (posedge s_axi_aclk) begin
+ if (s_axi_areset) begin
+ state <= IDLE;
+ addr <= 'd0;
+ rb_data <= 'd0;
+ wr_data <= 'd0;
+
+ count <= 10'd0;
+ rresp <= 2'd0;
+ bresp <= 2'd0;
+ end
+ else case (state)
+
+ IDLE: begin
+ if (s_axi_arvalid) begin
+ state <= READ_INIT;
+ addr <= s_axi_araddr[RP_AWIDTH-1:0];
+ end
+ else if (s_axi_awvalid) begin
+ state <= WRITE_INIT;
+ addr <= s_axi_awaddr[RP_AWIDTH-1:0];
+ end
+ end
+
+ READ_INIT: begin
+ state <= READ_IN_PROGRESS;
+ count <= 10'd0;
+ rresp <= 2'b00;
+ end
+
+ READ_IN_PROGRESS: begin
+ if (reg_port_out_ready) begin
+ rb_data <= reg_port_out_data;
+ state <= READ_DONE;
+ end
+ else if (count >= TIMEOUT) begin
+ state <= READ_DONE;
+ rresp <= 2'b10;
+ end
+ else begin
+ count <= count + 1'b1;
+ end
+ end
+
+ READ_DONE: begin
+ if (s_axi_rready) begin
+ state <= IDLE;
+ end
+ end
+
+ WRITE_INIT: begin
+ if (s_axi_wvalid) begin
+ wr_data <= s_axi_wdata[RP_DWIDTH-1:0];
+ state <= WRITE_IN_PROGRESS;
+ count <= 10'd0;
+ bresp <= 2'b00;
+ end
+ end
+
+ WRITE_IN_PROGRESS: begin
+ if (reg_port_out_ready) begin
+ state <= WRITE_DONE;
+ end
+ else if (count >= TIMEOUT) begin
+ state <= READ_DONE;
+ bresp <= 2'b10;
+ end
+ else begin
+ count <= count + 1'b1;
+ end
+ end
+
+ WRITE_DONE: begin
+ if (s_axi_bready)
+ state <= IDLE;
+ end
+
+ default: begin
+ state <= IDLE;
+ end
+
+ endcase
+ end
+
+ assign s_axi_awready = (state == IDLE);
+ assign s_axi_wready = (state == WRITE_INIT);
+ assign s_axi_bvalid = (state == WRITE_DONE);
+ assign s_axi_bresp = bresp;
+
+ assign s_axi_arready = (state == IDLE);
+ assign s_axi_rdata = rb_data;
+ assign s_axi_rvalid = (state == READ_DONE);
+ assign s_axi_rresp = rresp;
+
+ assign reg_port_in_wt = (state == WRITE_INIT) & s_axi_wvalid;
+ assign reg_port_in_data = (state == WRITE_INIT) ? s_axi_wdata : wr_data;
+ assign reg_port_in_addr = addr;
+
+ assign reg_port_in_rd = (state == READ_INIT);
+
+endmodule