blob: 92530fb0b70816011a6bdcdb2da3b897223323d0 [file] [log] [blame]
module axi_BR_allocator
#(
parameter AXI_USER_W = 6,
parameter N_INIT_PORT = 1,
parameter N_TARG_PORT = 7,
parameter AXI_DATA_W = 64,
parameter AXI_ID_IN = 16,
parameter LOG_N_TARG = $clog2(N_TARG_PORT),
parameter LOG_N_INIT = $clog2(N_INIT_PORT),
parameter AXI_ID_OUT = AXI_ID_IN + $clog2(N_TARG_PORT)
)
(
clk,
rst_n,
rid_i,
rdata_i,
rresp_i,
rlast_i,
ruser_i,
rvalid_i,
rready_o,
rid_o,
rdata_o,
rresp_o,
rlast_o,
ruser_o,
rvalid_o,
rready_i,
incr_req_i,
full_counter_o,
outstanding_trans_o,
error_req_i,
error_gnt_o,
error_len_i,
error_user_i,
error_id_i,
sample_ardata_info_i
);
//parameter AXI_USER_W = 6;
//parameter N_INIT_PORT = 1;
//parameter N_TARG_PORT = 7;
//parameter AXI_DATA_W = 64;
//parameter AXI_ID_IN = 16;
//parameter LOG_N_TARG = $clog2(N_TARG_PORT);
//parameter LOG_N_INIT = $clog2(N_INIT_PORT);
//parameter AXI_ID_OUT = AXI_ID_IN + $clog2(N_TARG_PORT);
input wire clk;
input wire rst_n;
input wire [(N_INIT_PORT * AXI_ID_OUT) - 1:0] rid_i;
input wire [(N_INIT_PORT * AXI_DATA_W) - 1:0] rdata_i;
input wire [(N_INIT_PORT * 2) - 1:0] rresp_i;
input wire [N_INIT_PORT - 1:0] rlast_i;
input wire [(N_INIT_PORT * AXI_USER_W) - 1:0] ruser_i;
input wire [N_INIT_PORT - 1:0] rvalid_i;
output wire [N_INIT_PORT - 1:0] rready_o;
output reg [AXI_ID_IN - 1:0] rid_o;
output reg [AXI_DATA_W - 1:0] rdata_o;
output reg [1:0] rresp_o;
output reg rlast_o;
output reg [AXI_USER_W - 1:0] ruser_o;
output reg rvalid_o;
input wire rready_i;
input wire incr_req_i;
output wire full_counter_o;
output wire outstanding_trans_o;
input wire error_req_i;
output reg error_gnt_o;
input wire [7:0] error_len_i;
input wire [AXI_USER_W - 1:0] error_user_i;
input wire [AXI_ID_IN - 1:0] error_id_i;
input wire sample_ardata_info_i;
localparam AUX_WIDTH = (AXI_DATA_W + 3) + AXI_USER_W;
wire [(N_INIT_PORT * AUX_WIDTH) - 1:0] AUX_VECTOR_IN;
wire [AUX_WIDTH - 1:0] AUX_VECTOR_OUT;
wire [(N_INIT_PORT * AXI_ID_IN) - 1:0] rid_int;
genvar i;
reg [9:0] outstanding_counter;
wire decr_req;
reg [1:0] CS;
reg [1:0] NS;
reg [7:0] CounterBurstCS;
reg [7:0] CounterBurstNS;
reg [7:0] error_len_S;
reg [AXI_USER_W - 1:0] error_user_S;
reg [AXI_ID_IN - 1:0] error_id_S;
wire [AXI_ID_IN - 1:0] rid_ARB_TREE;
wire [AXI_DATA_W - 1:0] rdata_ARB_TREE;
wire [1:0] rresp_ARB_TREE;
wire rlast_ARB_TREE;
wire [AXI_USER_W - 1:0] ruser_ARB_TREE;
wire rvalid_ARB_TREE;
reg rready_ARB_TREE;
assign outstanding_trans_o = (outstanding_counter == {10 {1'sb0}} ? 1'b0 : 1'b1);
assign decr_req = (rvalid_ARB_TREE & rready_ARB_TREE) & rlast_ARB_TREE;
assign full_counter_o = (outstanding_counter == {10 {1'sb1}} ? 1'b1 : 1'b0);
always @(posedge clk or negedge rst_n)
if (rst_n == 1'b0)
outstanding_counter <= 1'sb0;
else
case ({incr_req_i, decr_req})
2'b00: outstanding_counter <= outstanding_counter;
2'b01:
if (outstanding_counter != {10 {1'sb0}})
outstanding_counter <= outstanding_counter - 1'b1;
else
outstanding_counter <= 1'sb0;
2'b10:
if (outstanding_counter != {10 {1'sb1}})
outstanding_counter <= outstanding_counter + 1'b1;
else
outstanding_counter <= 1'sb1;
2'b11: outstanding_counter <= outstanding_counter;
endcase
always @(posedge clk or negedge rst_n)
if (rst_n == 1'b0) begin
CS <= 2'd0;
CounterBurstCS <= 1'sb0;
error_user_S <= 1'sb0;
error_id_S <= 1'sb0;
error_len_S <= 1'sb0;
end
else begin
CS <= NS;
CounterBurstCS <= CounterBurstNS;
if (sample_ardata_info_i) begin
error_user_S <= error_user_i;
error_id_S <= error_id_i;
error_len_S <= error_len_i;
end
end
always @(*) begin
rid_o = rid_ARB_TREE;
rdata_o = rdata_ARB_TREE;
rresp_o = rresp_ARB_TREE;
rlast_o = rlast_ARB_TREE;
ruser_o = ruser_ARB_TREE;
rvalid_o = rvalid_ARB_TREE;
rready_ARB_TREE = rready_i;
CounterBurstNS = CounterBurstCS;
error_gnt_o = 1'b0;
case (CS)
2'd0: begin
CounterBurstNS = 1'sb0;
rready_ARB_TREE = rready_i;
error_gnt_o = 1'b0;
if (error_req_i == 1'b1) begin
if (outstanding_trans_o == 1'b0) begin
if (error_len_i == {8 {1'sb0}})
NS = 2'd1;
else
NS = 2'd2;
end
else
NS = 2'd3;
end
else
NS = 2'd0;
end
2'd3: begin
CounterBurstNS = 1'sb0;
rready_ARB_TREE = rready_i;
error_gnt_o = 1'b0;
if (outstanding_trans_o == 1'b0) begin
if (error_len_S == {8 {1'sb0}})
NS = 2'd1;
else
NS = 2'd2;
end
else
NS = 2'd3;
end
2'd1: begin
rready_ARB_TREE = 1'b0;
CounterBurstNS = 1'sb0;
error_gnt_o = 1'b1;
rresp_o = 2'b11;
rdata_o = {AXI_DATA_W / 32 {32'hdeadbeef}};
rvalid_o = 1'b1;
ruser_o = error_user_S;
rlast_o = 1'b1;
rid_o = error_id_S;
if (rready_i)
NS = 2'd0;
else
NS = 2'd1;
end
2'd2: begin
rready_ARB_TREE = 1'b0;
rresp_o = 2'b11;
rdata_o = {AXI_DATA_W / 32 {32'hdeadbeef}};
rvalid_o = 1'b1;
ruser_o = error_user_S;
rid_o = error_id_S;
if (rready_i) begin
if (CounterBurstCS < error_len_i) begin
CounterBurstNS = CounterBurstCS + 1'b1;
error_gnt_o = 1'b0;
rlast_o = 1'b0;
NS = 2'd2;
end
else begin
error_gnt_o = 1'b1;
CounterBurstNS = 1'sb0;
NS = 2'd0;
rlast_o = 1'b1;
end
end
else begin
NS = 2'd2;
error_gnt_o = 1'b0;
end
end
default: begin
CounterBurstNS = 1'sb0;
NS = 2'd0;
error_gnt_o = 1'b0;
end
endcase
end
assign {ruser_ARB_TREE, rlast_ARB_TREE, rresp_ARB_TREE, rdata_ARB_TREE} = AUX_VECTOR_OUT;
generate
for (i = 0; i < N_INIT_PORT; i = i + 1) begin : AUX_VECTOR_BINDING
assign AUX_VECTOR_IN[i * AUX_WIDTH+:AUX_WIDTH] = {ruser_i[i * AXI_USER_W+:AXI_USER_W], rlast_i[i], rresp_i[i * 2+:2], rdata_i[i * AXI_DATA_W+:AXI_DATA_W]};
end
for (i = 0; i < N_INIT_PORT; i = i + 1) begin : RID_VECTOR_BINDING
assign rid_int[i * AXI_ID_IN+:AXI_ID_IN] = rid_i[(i * AXI_ID_OUT) + (AXI_ID_IN - 1)-:AXI_ID_IN];
end
if (N_INIT_PORT == 1) begin : DIRECT_BINDING
assign rvalid_ARB_TREE = rvalid_i;
assign AUX_VECTOR_OUT = AUX_VECTOR_IN;
assign rid_ARB_TREE = rid_int;
assign rready_o = rready_i;
end
else begin : ARB_TREE
axi_ArbitrationTree #(
.AUX_WIDTH(AUX_WIDTH),
.ID_WIDTH(AXI_ID_IN),
.N_MASTER(N_INIT_PORT)
) BR_ARB_TREE(
.clk(clk),
.rst_n(rst_n),
.data_req_i(rvalid_i),
.data_AUX_i(AUX_VECTOR_IN),
.data_ID_i(rid_int),
.data_gnt_o(rready_o),
.data_req_o(rvalid_ARB_TREE),
.data_AUX_o(AUX_VECTOR_OUT),
.data_ID_o(rid_ARB_TREE),
.data_gnt_i(rready_ARB_TREE),
.lock(1'b0),
.SEL_EXCLUSIVE({$clog2(N_INIT_PORT) {1'b0}})
);
end
endgenerate
endmodule