1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 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
|