// // 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