1// 2// Copyright 2016 Ettus Research 3// Copyright 2018 Ettus Research, a National Instruments Company 4// 5// SPDX-License-Identifier: LGPL-3.0-or-later 6// 7// AXI4lite to NI Register Port interface 8// 9 10module axil_to_ni_regport #( 11 parameter RP_AWIDTH = 16, 12 parameter RP_DWIDTH = 32, 13 parameter TIMEOUT = 512 14)( 15 input s_axi_aclk, 16 input s_axi_areset, 17 18 // AXI4lite interface 19 input [31:0] s_axi_awaddr, 20 input s_axi_awvalid, 21 output s_axi_awready, 22 input [31:0] s_axi_wdata, 23 input [3:0] s_axi_wstrb, 24 input s_axi_wvalid, 25 output s_axi_wready, 26 output [1:0] s_axi_bresp, 27 output s_axi_bvalid, 28 input s_axi_bready, 29 input [31:0] s_axi_araddr, 30 input s_axi_arvalid, 31 output s_axi_arready, 32 output [31:0] s_axi_rdata, 33 output [1:0] s_axi_rresp, 34 output s_axi_rvalid, 35 input s_axi_rready, 36 37 // RegPort interface, the out vs in 38 // is seen from the slave device 39 // hooked up to the regport 40 output reg_port_in_rd, 41 output reg_port_in_wt, 42 output [RP_AWIDTH-1:0] reg_port_in_addr, 43 output [RP_DWIDTH-1:0] reg_port_in_data, 44 input [RP_DWIDTH-1:0] reg_port_out_data, 45 input reg_port_out_ready 46); 47 48 localparam IDLE = 3'd0; 49 localparam READ_INIT = 3'd1; 50 localparam WRITE_INIT = 3'd2; 51 localparam READ_IN_PROGRESS = 3'd3; 52 localparam WRITE_IN_PROGRESS = 3'd4; 53 localparam WRITE_DONE = 3'd5; 54 localparam READ_DONE = 3'd6; 55 56 reg [RP_AWIDTH-1:0] addr; 57 reg [RP_DWIDTH-1:0] rb_data; 58 reg [RP_DWIDTH-1:0] wr_data; 59 reg [2:0] state; 60 reg [9:0] count; 61 reg [1:0] rresp; 62 reg [1:0] bresp; 63 64 always @ (posedge s_axi_aclk) begin 65 if (s_axi_areset) begin 66 state <= IDLE; 67 addr <= 'd0; 68 rb_data <= 'd0; 69 wr_data <= 'd0; 70 71 count <= 10'd0; 72 rresp <= 2'd0; 73 bresp <= 2'd0; 74 end 75 else case (state) 76 77 IDLE: begin 78 if (s_axi_arvalid) begin 79 state <= READ_INIT; 80 addr <= s_axi_araddr[RP_AWIDTH-1:0]; 81 end 82 else if (s_axi_awvalid) begin 83 state <= WRITE_INIT; 84 addr <= s_axi_awaddr[RP_AWIDTH-1:0]; 85 end 86 end 87 88 READ_INIT: begin 89 state <= READ_IN_PROGRESS; 90 count <= 10'd0; 91 rresp <= 2'b00; 92 end 93 94 READ_IN_PROGRESS: begin 95 if (reg_port_out_ready) begin 96 rb_data <= reg_port_out_data; 97 state <= READ_DONE; 98 end 99 else if (count >= TIMEOUT) begin 100 state <= READ_DONE; 101 rresp <= 2'b10; 102 end 103 else begin 104 count <= count + 1'b1; 105 end 106 end 107 108 READ_DONE: begin 109 if (s_axi_rready) begin 110 state <= IDLE; 111 end 112 end 113 114 WRITE_INIT: begin 115 if (s_axi_wvalid) begin 116 wr_data <= s_axi_wdata[RP_DWIDTH-1:0]; 117 state <= WRITE_IN_PROGRESS; 118 count <= 10'd0; 119 bresp <= 2'b00; 120 end 121 end 122 123 WRITE_IN_PROGRESS: begin 124 if (reg_port_out_ready) begin 125 state <= WRITE_DONE; 126 end 127 else if (count >= TIMEOUT) begin 128 state <= READ_DONE; 129 bresp <= 2'b10; 130 end 131 else begin 132 count <= count + 1'b1; 133 end 134 end 135 136 WRITE_DONE: begin 137 if (s_axi_bready) 138 state <= IDLE; 139 end 140 141 default: begin 142 state <= IDLE; 143 end 144 145 endcase 146 end 147 148 assign s_axi_awready = (state == IDLE); 149 assign s_axi_wready = (state == WRITE_INIT); 150 assign s_axi_bvalid = (state == WRITE_DONE); 151 assign s_axi_bresp = bresp; 152 153 assign s_axi_arready = (state == IDLE); 154 assign s_axi_rdata = rb_data; 155 assign s_axi_rvalid = (state == READ_DONE); 156 assign s_axi_rresp = rresp; 157 158 assign reg_port_in_wt = (state == WRITE_INIT) & s_axi_wvalid; 159 assign reg_port_in_data = (state == WRITE_INIT) ? s_axi_wdata : wr_data; 160 assign reg_port_in_addr = addr; 161 162 assign reg_port_in_rd = (state == READ_INIT); 163 164endmodule 165