blob: 900ba26e6b55d383cecd62b9f39ef970061b0d3f [file] [log] [blame]
module spi_slave_axi_plug
#(
parameter AXI_ADDR_WIDTH = 32,
parameter AXI_DATA_WIDTH = 64,
parameter AXI_USER_WIDTH = 6,
parameter AXI_ID_WIDTH = 3
)
(
axi_aclk,
axi_aresetn,
axi_master_aw_valid,
axi_master_aw_addr,
axi_master_aw_prot,
axi_master_aw_region,
axi_master_aw_len,
axi_master_aw_size,
axi_master_aw_burst,
axi_master_aw_lock,
axi_master_aw_cache,
axi_master_aw_qos,
axi_master_aw_id,
axi_master_aw_user,
axi_master_aw_ready,
axi_master_ar_valid,
axi_master_ar_addr,
axi_master_ar_prot,
axi_master_ar_region,
axi_master_ar_len,
axi_master_ar_size,
axi_master_ar_burst,
axi_master_ar_lock,
axi_master_ar_cache,
axi_master_ar_qos,
axi_master_ar_id,
axi_master_ar_user,
axi_master_ar_ready,
axi_master_w_valid,
axi_master_w_data,
axi_master_w_strb,
axi_master_w_user,
axi_master_w_last,
axi_master_w_ready,
axi_master_r_valid,
axi_master_r_data,
axi_master_r_resp,
axi_master_r_last,
axi_master_r_id,
axi_master_r_user,
axi_master_r_ready,
axi_master_b_valid,
axi_master_b_resp,
axi_master_b_id,
axi_master_b_user,
axi_master_b_ready,
rxtx_addr,
rxtx_addr_valid,
start_tx,
cs,
tx_data,
tx_valid,
tx_ready,
rx_data,
rx_valid,
rx_ready,
wrap_length
);
//parameter AXI_ADDR_WIDTH = 32;
//parameter AXI_DATA_WIDTH = 64;
//parameter AXI_USER_WIDTH = 6;
//parameter AXI_ID_WIDTH = 3;
input wire axi_aclk;
input wire axi_aresetn;
output reg axi_master_aw_valid;
output wire [AXI_ADDR_WIDTH - 1:0] axi_master_aw_addr;
output wire [2:0] axi_master_aw_prot;
output wire [3:0] axi_master_aw_region;
output wire [7:0] axi_master_aw_len;
output wire [2:0] axi_master_aw_size;
output wire [1:0] axi_master_aw_burst;
output wire axi_master_aw_lock;
output wire [3:0] axi_master_aw_cache;
output wire [3:0] axi_master_aw_qos;
output wire [AXI_ID_WIDTH - 1:0] axi_master_aw_id;
output wire [AXI_USER_WIDTH - 1:0] axi_master_aw_user;
input wire axi_master_aw_ready;
output reg axi_master_ar_valid;
output wire [AXI_ADDR_WIDTH - 1:0] axi_master_ar_addr;
output wire [2:0] axi_master_ar_prot;
output wire [3:0] axi_master_ar_region;
output wire [7:0] axi_master_ar_len;
output wire [2:0] axi_master_ar_size;
output wire [1:0] axi_master_ar_burst;
output wire axi_master_ar_lock;
output wire [3:0] axi_master_ar_cache;
output wire [3:0] axi_master_ar_qos;
output wire [AXI_ID_WIDTH - 1:0] axi_master_ar_id;
output wire [AXI_USER_WIDTH - 1:0] axi_master_ar_user;
input wire axi_master_ar_ready;
output reg axi_master_w_valid;
output wire [AXI_DATA_WIDTH - 1:0] axi_master_w_data;
output wire [(AXI_DATA_WIDTH / 8) - 1:0] axi_master_w_strb;
output wire [AXI_USER_WIDTH - 1:0] axi_master_w_user;
output wire axi_master_w_last;
input wire axi_master_w_ready;
input wire axi_master_r_valid;
input wire [AXI_DATA_WIDTH - 1:0] axi_master_r_data;
input wire [1:0] axi_master_r_resp;
input wire axi_master_r_last;
input wire [AXI_ID_WIDTH - 1:0] axi_master_r_id;
input wire [AXI_USER_WIDTH - 1:0] axi_master_r_user;
output reg axi_master_r_ready;
input wire axi_master_b_valid;
input wire [1:0] axi_master_b_resp;
input wire [AXI_ID_WIDTH - 1:0] axi_master_b_id;
input wire [AXI_USER_WIDTH - 1:0] axi_master_b_user;
output reg axi_master_b_ready;
input wire [AXI_ADDR_WIDTH - 1:0] rxtx_addr;
input wire rxtx_addr_valid;
input wire start_tx;
input wire cs;
output wire [31:0] tx_data;
output reg tx_valid;
input wire tx_ready;
input wire [31:0] rx_data;
input wire rx_valid;
output reg rx_ready;
input wire [15:0] wrap_length;
reg [AXI_ADDR_WIDTH - 1:0] curr_addr;
reg [AXI_ADDR_WIDTH - 1:0] next_addr;
reg [31:0] curr_data_rx;
reg [AXI_DATA_WIDTH - 1:0] curr_data_tx;
reg incr_addr_w;
reg incr_addr_r;
reg sample_fifo;
reg sample_axidata;
reg [15:0] tx_counter;
reg [2:0] AR_CS;
reg [2:0] AR_NS;
reg [2:0] AW_CS;
reg [2:0] AW_NS;
always @(posedge axi_aclk or negedge axi_aresetn)
if (axi_aresetn == 0) begin
AW_CS <= 3'd0;
AR_CS <= 3'd0;
curr_data_rx <= 'h0;
curr_data_tx <= 'h0;
curr_addr <= 'h0;
end
else begin
AW_CS <= AW_NS;
AR_CS <= AR_NS;
if (sample_fifo)
curr_data_rx <= rx_data;
if (sample_axidata)
curr_data_tx <= axi_master_r_data;
if (rxtx_addr_valid)
curr_addr <= rxtx_addr;
else if (incr_addr_w | incr_addr_r)
curr_addr <= next_addr;
end
always @(posedge axi_aclk or negedge axi_aresetn)
if (axi_aresetn == 1'b0)
tx_counter <= 16'h0000;
else if (start_tx)
tx_counter <= 16'h0000;
else if (incr_addr_w | incr_addr_r)
if (tx_counter == (wrap_length - 1))
tx_counter <= 16'h0000;
else
tx_counter <= tx_counter + 16'h0001;
always @(*) begin
next_addr = 32'b00000000000000000000000000000000;
if (rxtx_addr_valid)
next_addr = rxtx_addr;
else if (tx_counter == (wrap_length - 1))
next_addr = rxtx_addr;
else
next_addr = curr_addr + 32'h00000004;
end
always @(*) begin
AW_NS = 3'd0;
sample_fifo = 1'b0;
rx_ready = 1'b0;
axi_master_aw_valid = 1'b0;
axi_master_w_valid = 1'b0;
axi_master_b_ready = 1'b0;
incr_addr_w = 1'b0;
case (AW_CS)
3'd0:
if (rx_valid) begin
sample_fifo = 1'b1;
rx_ready = 1'b1;
AW_NS = 3'd2;
end
else
AW_NS = 3'd0;
3'd2: begin
axi_master_aw_valid = 1'b1;
if (axi_master_aw_ready)
AW_NS = 3'd3;
else
AW_NS = 3'd2;
end
3'd3: begin
axi_master_w_valid = 1'b1;
if (axi_master_w_ready) begin
incr_addr_w = 1'b1;
AW_NS = 3'd4;
end
else
AW_NS = 3'd3;
end
3'd4: begin
axi_master_b_ready = 1'b1;
if (axi_master_b_valid)
AW_NS = 3'd0;
else
AW_NS = 3'd4;
end
endcase
end
always @(*) begin
AR_NS = 3'd0;
tx_valid = 1'b0;
axi_master_ar_valid = 1'b0;
axi_master_r_ready = 1'b0;
incr_addr_r = 1'b0;
sample_axidata = 1'b0;
case (AR_CS)
3'd0:
if (start_tx && !cs)
AR_NS = 3'd2;
else
AR_NS = 3'd0;
3'd1: begin
tx_valid = 1'b1;
if (cs)
AR_NS = 3'd0;
else if (tx_ready) begin
incr_addr_r = 1'b1;
AR_NS = 3'd2;
end
else
AR_NS = 3'd1;
end
3'd2: begin
axi_master_ar_valid = 1'b1;
if (axi_master_ar_ready)
AR_NS = 3'd4;
else
AR_NS = 3'd2;
end
3'd4: begin
axi_master_r_ready = 1'b1;
if (axi_master_r_valid) begin
sample_axidata = 1'b1;
AR_NS = 3'd1;
end
else
AR_NS = 3'd4;
end
endcase
end
generate
if (AXI_DATA_WIDTH == 32) begin : genblk1
assign tx_data = curr_data_tx[31:0];
end
else begin : genblk1
assign tx_data = (curr_addr[2] ? curr_data_tx[63:32] : curr_data_tx[31:0]);
end
endgenerate
assign axi_master_aw_addr = curr_addr;
assign axi_master_aw_prot = 'h0;
assign axi_master_aw_region = 'h0;
assign axi_master_aw_len = 'h0;
assign axi_master_aw_size = 3'b010;
assign axi_master_aw_burst = 'h0;
assign axi_master_aw_lock = 'h0;
assign axi_master_aw_cache = 'h0;
assign axi_master_aw_qos = 'h0;
assign axi_master_aw_id = 'h1;
assign axi_master_aw_user = 'h0;
assign axi_master_w_data = {AXI_DATA_WIDTH / 32 {curr_data_rx}};
generate
if (AXI_DATA_WIDTH == 32) begin : genblk2
assign axi_master_w_strb = 4'hf;
end
else begin : genblk2
assign axi_master_w_strb = (curr_addr[2] ? 8'hf0 : 8'h0f);
end
endgenerate
assign axi_master_w_user = 'h0;
assign axi_master_w_last = 1'b1;
assign axi_master_ar_addr = curr_addr;
assign axi_master_ar_prot = 'h0;
assign axi_master_ar_region = 'h0;
assign axi_master_ar_len = 'h0;
assign axi_master_ar_size = 3'b010;
assign axi_master_ar_burst = 'h0;
assign axi_master_ar_lock = 'h0;
assign axi_master_ar_cache = 'h0;
assign axi_master_ar_qos = 'h0;
assign axi_master_ar_id = 'h1;
assign axi_master_ar_user = 'h0;
endmodule