blob: 3f9bad532412ff3c2ba871aa65184035c441622e [file] [log] [blame]
module axi_DW_allocator
#(
parameter AXI_USER_W = 6,
parameter N_TARG_PORT = 7,
parameter LOG_N_TARG = $clog2(N_TARG_PORT),
parameter FIFO_DEPTH = 8,
parameter AXI_DATA_W = 64,
parameter AXI_NUMBYTES = AXI_DATA_W/8
)
(
clk,
rst_n,
test_en_i,
wdata_i,
wstrb_i,
wlast_i,
wuser_i,
wvalid_i,
wready_o,
wdata_o,
wstrb_o,
wlast_o,
wuser_o,
wvalid_o,
wready_i,
push_ID_i,
ID_i,
grant_FIFO_ID_o
);
//parameter AXI_USER_W = 6;
//parameter N_TARG_PORT = 7;
//parameter LOG_N_TARG = $clog2(N_TARG_PORT);
//parameter FIFO_DEPTH = 8;
//parameter AXI_DATA_W = 64;
//parameter AXI_NUMBYTES = AXI_DATA_W / 8;
input wire clk;
input wire rst_n;
input wire test_en_i;
input wire [(N_TARG_PORT * AXI_DATA_W) - 1:0] wdata_i;
input wire [(N_TARG_PORT * AXI_NUMBYTES) - 1:0] wstrb_i;
input wire [N_TARG_PORT - 1:0] wlast_i;
input wire [(N_TARG_PORT * AXI_USER_W) - 1:0] wuser_i;
input wire [N_TARG_PORT - 1:0] wvalid_i;
output reg [N_TARG_PORT - 1:0] wready_o;
output wire [AXI_DATA_W - 1:0] wdata_o;
output wire [AXI_NUMBYTES - 1:0] wstrb_o;
output wire wlast_o;
output wire [AXI_USER_W - 1:0] wuser_o;
output reg wvalid_o;
input wire wready_i;
input wire push_ID_i;
input wire [(LOG_N_TARG + N_TARG_PORT) - 1:0] ID_i;
output wire grant_FIFO_ID_o;
localparam AUX_WIDTH = ((AXI_DATA_W + AXI_NUMBYTES) + 1) + AXI_USER_W;
reg pop_from_ID_FIFO;
wire valid_ID;
wire [(LOG_N_TARG + N_TARG_PORT) - 1:0] ID_int;
wire [LOG_N_TARG - 1:0] ID_int_BIN;
wire [N_TARG_PORT - 1:0] ID_int_OH;
wire [AUX_WIDTH - 1:0] AUX_VECTOR_OUT;
wire [(N_TARG_PORT * AUX_WIDTH) - 1:0] AUX_VECTOR_IN;
reg CS;
reg NS;
genvar i;
generate
for (i = 0; i < N_TARG_PORT; i = i + 1) begin : AUX_VECTOR_BINDING
assign AUX_VECTOR_IN[i * AUX_WIDTH+:AUX_WIDTH] = {wdata_i[i * AXI_DATA_W+:AXI_DATA_W], wstrb_i[i * AXI_NUMBYTES+:AXI_NUMBYTES], wlast_i[i], wuser_i[i * AXI_USER_W+:AXI_USER_W]};
end
endgenerate
assign {wdata_o, wstrb_o, wlast_o, wuser_o} = AUX_VECTOR_OUT;
generic_fifo #(
.DATA_WIDTH(LOG_N_TARG + N_TARG_PORT),
.DATA_DEPTH(FIFO_DEPTH)
) MASTER_ID_FIFO(
.clk(clk),
.rst_n(rst_n),
.test_mode_i(test_en_i),
.data_i(ID_i),
.valid_i(push_ID_i),
.grant_o(grant_FIFO_ID_o),
.data_o(ID_int),
.valid_o(valid_ID),
.grant_i(pop_from_ID_FIFO)
);
assign ID_int_BIN = ID_int[(LOG_N_TARG + N_TARG_PORT) - 1:N_TARG_PORT];
assign ID_int_OH = ID_int[N_TARG_PORT - 1:0];
always @(posedge clk or negedge rst_n) begin : UPDATE_STATE_FSM
if (rst_n == 1'b0)
CS <= 1'd0;
else
CS <= NS;
end
always @(*) begin : NEXT_STATE_FSM
pop_from_ID_FIFO = 1'b0;
wvalid_o = 1'b0;
wready_o = 1'sb0;
case (CS)
1'd0: begin : _CS_IN_SINGLE_IDLE
if (valid_ID) begin : _valid_ID
wvalid_o = wvalid_i[ID_int_BIN];
wready_o = {N_TARG_PORT {wready_i}} & ID_int_OH;
if (wvalid_i[ID_int_BIN] & wready_i) begin : _granted_request
if (wlast_i[ID_int_BIN]) begin : _last_packet
NS = 1'd0;
pop_from_ID_FIFO = 1'b1;
end
else begin : _payload_packet
NS = 1'd1;
pop_from_ID_FIFO = 1'b0;
end
end
else begin : _not_granted_request
NS = 1'd0;
pop_from_ID_FIFO = 1'b0;
end
end
else begin : _not_valid_ID
NS = 1'd0;
pop_from_ID_FIFO = 1'b0;
wvalid_o = 1'b0;
wready_o = 1'sb0;
end
end
1'd1: begin : _CS_IN_BUSRT
wvalid_o = wvalid_i[ID_int_BIN];
wready_o = ({N_TARG_PORT {wready_i}} & ID_int_OH) & {N_TARG_PORT {valid_ID}};
if (wvalid_i[ID_int_BIN] & wready_i) begin
if (wlast_i[ID_int_BIN]) begin
NS = 1'd0;
pop_from_ID_FIFO = 1'b1;
end
else begin
NS = 1'd1;
pop_from_ID_FIFO = 1'b0;
end
end
else begin
NS = 1'd1;
pop_from_ID_FIFO = 1'b0;
end
end
default: begin
NS = 1'd0;
pop_from_ID_FIFO = 1'b0;
wvalid_o = 1'b0;
wready_o = 1'sb0;
end
endcase
end
axi_multiplexer #(
.DATA_WIDTH(AUX_WIDTH),
.N_IN(N_TARG_PORT)
) WRITE_DATA_MUX(
.IN_DATA(AUX_VECTOR_IN),
.OUT_DATA(AUX_VECTOR_OUT),
.SEL(ID_int_BIN)
);
endmodule