data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi/src/axi_lite_xbar.sv
1: b"%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi/src/axi_lite_xbar.sv:14: syntax error, unexpected IDENTIFIER, expecting PACKAGE-IDENTIFIER or STRING\nimport axi_pkg::*;\n       ^~~~~~~\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi/src/axi_lite_xbar.sv:222: syntax error, unexpected '[', expecting IDENTIFIER\n  resp_t [NUM_SLAVE-1:0] slave_rresp_pack;\n         ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi/src/axi_lite_xbar.sv:227: syntax error, unexpected '[', expecting IDENTIFIER\n  resp_t [NUM_SLAVE-1:0] slave_bresp_pack;\n         ^\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi/src/axi_lite_xbar.sv:369: syntax error, unexpected ::, expecting ';'\n        master_rresp  = axi_pkg::RESP_DECERR;\n                               ^~\n                                                                                                                          : ... Perhaps 'axi_pkg' is a package which needs to be predeclared? (IEEE 1800-2017 26.3)\n%Error: data/full_repos/permissive/509468557/generators/cva6/src/main/resources/vsrc/cva6/src/axi/src/axi_lite_xbar.sv:454: syntax error, unexpected ::, expecting ';'\n        master_bresp  = axi_pkg::RESP_DECERR;\n                               ^~\n%Error: Exiting due to 5 error(s)\n"
module axi_lite_xbar_simple #(

  parameter int ADDR_WIDTH = -1,

  parameter int DATA_WIDTH = -1,

  parameter int NUM_MASTER = 1,

  parameter int NUM_SLAVE = 1,

  parameter int NUM_RULES = -1
)(
  input logic            clk_i               ,
  input logic            rst_ni              ,
  AXI_LITE.Slave         master [NUM_MASTER] ,
  AXI_LITE.Master        slave  [NUM_SLAVE]  ,
  AXI_ROUTING_RULES.xbar rules               ,
  AXI_ARBITRATION.req    arb_rd              ,
  AXI_ARBITRATION.req    arb_wr
);

  `ifndef SYNTHESIS
  initial begin
    assert(NUM_MASTER > 0);
    assert(NUM_SLAVE > 0);
    assert(NUM_RULES > 0);
    assert(rules.AXI_ADDR_WIDTH == ADDR_WIDTH);
    assert(rules.NUM_SLAVE == NUM_SLAVE);
  end


  for (genvar i = 0; i < NUM_MASTER; i++) begin : g_chk_master
    initial begin
      assert(master[i].AXI_ADDR_WIDTH == ADDR_WIDTH);
      assert(master[i].AXI_DATA_WIDTH == DATA_WIDTH);
    end
  end


  for (genvar i = 0; i < NUM_SLAVE; i++) begin
    initial begin
      assert(slave[i].AXI_ADDR_WIDTH == ADDR_WIDTH);
      assert(slave[i].AXI_DATA_WIDTH == DATA_WIDTH);
    end
  end
  `endif

  typedef logic [ADDR_WIDTH-1:0]   addr_t;
  typedef logic [DATA_WIDTH-1:0]   data_t;
  typedef logic [DATA_WIDTH/8-1:0] strb_t;

  typedef logic [$clog2(NUM_MASTER)-1:0] master_id_t;
  typedef logic [$clog2(NUM_SLAVE)-1:0]  slave_id_t;



  struct packed {
    master_id_t master;
    slave_id_t  slave;
  } tag_rd_d, tag_wr_d, tag_rd_q, tag_wr_q;

  enum { RD_IDLE, RD_REQ, RD_RESP, RD_ERR_RESP } state_rd_d, state_rd_q;
  enum { WR_IDLE, WR_REQ, WR_DATA, WR_RESP, WR_ERR_DATA, WR_ERR_RESP } state_wr_d, state_wr_q;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (~rst_ni) begin
      state_rd_q <= RD_IDLE;
      state_wr_q <= WR_IDLE;
      tag_rd_q <= '0;
      tag_wr_q <= '0;
    end else begin
      state_rd_q <= state_rd_d;
      state_wr_q <= state_wr_d;
      tag_rd_q <= tag_rd_d;
      tag_wr_q <= tag_wr_d;
    end
  end



  master_id_t master_sel_rd, master_sel_wr;

  addr_t [NUM_MASTER-1:0] master_araddr_pack;
  logic  [NUM_MASTER-1:0] master_rready_pack;

  addr_t [NUM_MASTER-1:0] master_awaddr_pack;
  data_t [NUM_MASTER-1:0] master_wdata_pack;
  strb_t [NUM_MASTER-1:0] master_wstrb_pack;
  logic  [NUM_MASTER-1:0] master_wvalid_pack;
  logic  [NUM_MASTER-1:0] master_bready_pack;

  addr_t master_araddr;
  logic  master_arready;
  data_t master_rdata;
  resp_t master_rresp;
  logic  master_rvalid;
  logic  master_rready;

  addr_t master_awaddr;
  logic  master_awready;
  data_t master_wdata;
  strb_t master_wstrb;
  logic  master_wvalid;
  logic  master_wready;
  resp_t master_bresp;
  logic  master_bvalid;
  logic  master_bready;

  for (genvar i = 0; i < NUM_MASTER; i++) begin
    assign master_araddr_pack[i]   = master[i].ar_addr;
    assign master[i].ar_ready      = master_arready && (i == master_sel_rd);
    assign master[i].r_data        = master_rdata;
    assign master[i].r_resp        = master_rresp;
    assign master[i].r_valid       = master_rvalid && (i == master_sel_rd);
    assign master_rready_pack[i]   = master[i].r_ready;

    assign master_awaddr_pack[i]   = master[i].aw_addr;
    assign master[i].aw_ready      = master_awready && (i == master_sel_wr);
    assign master_wdata_pack[i]    = master[i].w_data;
    assign master_wstrb_pack[i]    = master[i].w_strb;
    assign master_wvalid_pack[i]   = master[i].w_valid;
    assign master[i].w_ready       = master_wready && (i == master_sel_wr);
    assign master[i].b_resp        = master_bresp;
    assign master_bready_pack[i]   = master[i].b_ready;
    assign master[i].b_valid       = master_bvalid && (i == master_sel_wr);
  end

  assign master_araddr  = master_araddr_pack  [master_sel_rd];
  assign master_rready  = master_rready_pack  [master_sel_rd];

  assign master_awaddr  = master_awaddr_pack  [master_sel_wr];
  assign master_wdata   = master_wdata_pack   [master_sel_wr];
  assign master_wstrb   = master_wstrb_pack   [master_sel_wr];
  assign master_wvalid  = master_wvalid_pack  [master_sel_wr];
  assign master_bready  = master_bready_pack  [master_sel_wr];



  slave_id_t slave_sel_rd, slave_sel_wr;

  logic  [NUM_SLAVE-1:0] slave_arready_pack;
  data_t [NUM_SLAVE-1:0] slave_rdata_pack;
  resp_t [NUM_SLAVE-1:0] slave_rresp_pack;
  logic  [NUM_SLAVE-1:0] slave_rvalid_pack;

  logic  [NUM_SLAVE-1:0] slave_awready_pack;
  logic  [NUM_SLAVE-1:0] slave_wready_pack;
  resp_t [NUM_SLAVE-1:0] slave_bresp_pack;
  logic  [NUM_SLAVE-1:0] slave_bvalid_pack;

  addr_t slave_araddr;
  logic  slave_arvalid;
  logic  slave_arready;
  data_t slave_rdata;
  resp_t slave_rresp;
  logic  slave_rvalid;
  logic  slave_rready;

  addr_t slave_awaddr;
  logic  slave_awvalid;
  logic  slave_awready;
  data_t slave_wdata;
  strb_t slave_wstrb;
  logic  slave_wvalid;
  logic  slave_wready;
  resp_t slave_bresp;
  logic  slave_bvalid;
  logic  slave_bready;

  for (genvar i = 0; i < NUM_SLAVE; i++) begin
    assign slave[i].ar_addr      = slave_araddr;
    assign slave[i].ar_valid     = slave_arvalid && (i == slave_sel_rd);
    assign slave_arready_pack[i] = slave[i].ar_ready;
    assign slave_rdata_pack[i]   = slave[i].r_data;
    assign slave_rresp_pack[i]   = slave[i].r_resp;
    assign slave_rvalid_pack[i]  = slave[i].r_valid;
    assign slave[i].r_ready      = slave_rready && (i == slave_sel_rd);

    assign slave[i].aw_addr      = slave_awaddr;
    assign slave[i].aw_valid     = slave_awvalid && (i == slave_sel_wr);
    assign slave_awready_pack[i] = slave[i].aw_ready;
    assign slave[i].w_data       = slave_wdata;
    assign slave[i].w_strb       = slave_wstrb;
    assign slave[i].w_valid      = slave_wvalid && (i == slave_sel_wr);
    assign slave_wready_pack[i]  = slave[i].w_ready;
    assign slave_bresp_pack[i]   = slave[i].b_resp;
    assign slave_bvalid_pack[i]  = slave[i].b_valid;
    assign slave[i].b_ready      = slave_bready && (i == slave_sel_wr);
  end

  assign slave_arready = slave_arready_pack [slave_sel_rd];
  assign slave_rdata   = slave_rdata_pack   [slave_sel_rd];
  assign slave_rresp   = slave_rresp_pack   [slave_sel_rd];
  assign slave_rvalid  = slave_rvalid_pack  [slave_sel_rd];

  assign slave_awready = slave_awready_pack [slave_sel_wr];
  assign slave_wready  = slave_wready_pack  [slave_sel_wr];
  assign slave_bresp   = slave_bresp_pack   [slave_sel_wr];
  assign slave_bvalid  = slave_bvalid_pack  [slave_sel_wr];



  for (genvar i = 0; i < NUM_MASTER; i++) begin
    assign arb_rd.in_req[i] = master[i].ar_valid;
    assign arb_wr.in_req[i] = master[i].aw_valid;
  end


  addr_t rd_resolve_addr, wr_resolve_addr;
  logic [$clog2(NUM_SLAVE)-1:0] rd_match_idx, wr_match_idx;
  logic rd_match_ok, wr_match_ok;

  axi_address_resolver #(
    .ADDR_WIDTH( ADDR_WIDTH ),
    .NUM_SLAVE ( NUM_SLAVE  ),
    .NUM_RULES ( NUM_RULES  )
  ) i_rd_resolver (
    .rules       ( rules           ),
    .addr_i      ( rd_resolve_addr ),
    .match_idx_o ( rd_match_idx    ),
    .match_ok_o  ( rd_match_ok     )
  );

  axi_address_resolver #(
    .ADDR_WIDTH( ADDR_WIDTH ),
    .NUM_SLAVE ( NUM_SLAVE  ),
    .NUM_RULES ( NUM_RULES  )
  ) i_wr_resolver (
    .rules       ( rules           ),
    .addr_i      ( wr_resolve_addr ),
    .match_idx_o ( wr_match_idx    ),
    .match_ok_o  ( wr_match_ok     )
  );


  always_comb begin
    state_rd_d      = state_rd_q;
    tag_rd_d        = tag_rd_q;

    arb_rd.out_ack  = 0;
    master_sel_rd   = tag_rd_q.master;
    slave_sel_rd    = tag_rd_q.slave;
    rd_resolve_addr = master_araddr;

    slave_araddr    = master_araddr;
    slave_arvalid   = 0;
    master_arready  = 0;
    master_rdata    = slave_rdata;
    master_rresp    = slave_rresp;
    master_rvalid   = 0;
    slave_rready    = 0;

    case (state_rd_q)
      RD_IDLE: begin
        master_sel_rd = arb_rd.out_sel;
        if (arb_rd.out_req) begin
          arb_rd.out_ack  = 1;
          tag_rd_d.master = arb_rd.out_sel;
          state_rd_d      = RD_REQ;
        end
      end

      RD_REQ: begin
        slave_sel_rd   = rd_match_idx;
        tag_rd_d.slave = rd_match_idx;


        if (rd_match_ok) begin
          slave_arvalid = 1;
          if (slave_arready) begin
            state_rd_d     = RD_RESP;
            master_arready = 1;
          end
        end else begin
          state_rd_d     = RD_ERR_RESP;
          master_arready = 1;
        end
      end

      RD_RESP: begin
        master_rvalid = slave_rvalid;
        slave_rready = master_rready;
        if (slave_rvalid && master_rready) begin
          state_rd_d = RD_IDLE;
        end
      end


      RD_ERR_RESP: begin
        master_rresp  = axi_pkg::RESP_DECERR;
        master_rvalid = 1;
        if (master_rready) begin
          state_rd_d = RD_IDLE;
        end
      end

      default: state_rd_d = RD_IDLE;
    endcase
  end


  always_comb begin
    state_wr_d = state_wr_q;
    tag_wr_d   = tag_wr_q;

    arb_wr.out_ack  = 0;
    master_sel_wr   = tag_wr_q.master;
    slave_sel_wr    = tag_wr_q.slave;
    wr_resolve_addr = master_awaddr;

    slave_awaddr    = master_awaddr;
    slave_awvalid   = 0;
    master_awready  = 0;
    slave_wdata     = master_wdata;
    slave_wstrb     = master_wstrb;
    slave_wvalid    = 0;
    master_wready   = 0;
    master_bresp    = slave_bresp;
    master_bvalid   = 0;
    slave_bready    = 0;

    case (state_wr_q)
      WR_IDLE: begin
        master_sel_wr = arb_wr.out_sel;
        if (arb_wr.out_req) begin
          arb_wr.out_ack  = 1;
          tag_wr_d.master = arb_wr.out_sel;
          state_wr_d      = WR_REQ;
        end
      end

      WR_REQ: begin
        slave_sel_wr   = wr_match_idx;
        tag_wr_d.slave = wr_match_idx;


        if (wr_match_ok) begin
          slave_awvalid = 1;
          if (slave_awready) begin
            state_wr_d     = WR_DATA;
            master_awready = 1;
          end
        end else begin
          state_wr_d     = WR_ERR_DATA;
          master_awready = 1;
        end
      end

      WR_DATA: begin
        master_wready = slave_wready;
        slave_wvalid = master_wvalid;
        if (slave_wvalid && master_wready) begin
          state_wr_d = WR_RESP;
        end
      end

      WR_RESP: begin
        master_bvalid = slave_bvalid;
        slave_bready = master_bready;
        if (slave_bvalid && master_bready) begin
          state_wr_d = WR_IDLE;
        end
      end


      WR_ERR_DATA: begin
        master_wready = 1;
        if (master_wvalid) begin
          state_wr_d = WR_ERR_RESP;
        end
      end


      WR_ERR_RESP: begin
        master_bresp  = axi_pkg::RESP_DECERR;
        master_bvalid = 1;
        if (master_bready) begin
          state_wr_d = WR_IDLE;
        end
      end

      default: state_wr_d = WR_IDLE;
    endcase
  end

endmodule
module axi_lite_xbar_simple #(

  parameter int ADDR_WIDTH = -1,

  parameter int DATA_WIDTH = -1,

  parameter int NUM_MASTER = 1,

  parameter int NUM_SLAVE = 1,

  parameter int NUM_RULES = -1
)(
  input logic            clk_i               ,
  input logic            rst_ni              ,
  AXI_LITE.Slave         master [NUM_MASTER] ,
  AXI_LITE.Master        slave  [NUM_SLAVE]  ,
  AXI_ROUTING_RULES.xbar rules               ,
  AXI_ARBITRATION.req    arb_rd              ,
  AXI_ARBITRATION.req    arb_wr
);


  `ifndef SYNTHESIS
  initial begin
    assert(NUM_MASTER > 0);
    assert(NUM_SLAVE > 0);
    assert(NUM_RULES > 0);
    assert(rules.AXI_ADDR_WIDTH == ADDR_WIDTH);
    assert(rules.NUM_SLAVE == NUM_SLAVE);
  end


  for (genvar i = 0; i < NUM_MASTER; i++) begin : g_chk_master
    initial begin
      assert(master[i].AXI_ADDR_WIDTH == ADDR_WIDTH);
      assert(master[i].AXI_DATA_WIDTH == DATA_WIDTH);
    end
  end


  for (genvar i = 0; i < NUM_SLAVE; i++) begin
    initial begin
      assert(slave[i].AXI_ADDR_WIDTH == ADDR_WIDTH);
      assert(slave[i].AXI_DATA_WIDTH == DATA_WIDTH);
    end
  end
  `endif

  typedef logic [ADDR_WIDTH-1:0]   addr_t;
  typedef logic [DATA_WIDTH-1:0]   data_t;
  typedef logic [DATA_WIDTH/8-1:0] strb_t;

  typedef logic [$clog2(NUM_MASTER)-1:0] master_id_t;
  typedef logic [$clog2(NUM_SLAVE)-1:0]  slave_id_t;



  struct packed {
    master_id_t master;
    slave_id_t  slave;
  } tag_rd_d, tag_wr_d, tag_rd_q, tag_wr_q;

  enum { RD_IDLE, RD_REQ, RD_RESP, RD_ERR_RESP } state_rd_d, state_rd_q;
  enum { WR_IDLE, WR_REQ, WR_DATA, WR_RESP, WR_ERR_DATA, WR_ERR_RESP } state_wr_d, state_wr_q;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (~rst_ni) begin
      state_rd_q <= RD_IDLE;
      state_wr_q <= WR_IDLE;
      tag_rd_q <= '0;
      tag_wr_q <= '0;
    end else begin
      state_rd_q <= state_rd_d;
      state_wr_q <= state_wr_d;
      tag_rd_q <= tag_rd_d;
      tag_wr_q <= tag_wr_d;
    end
  end



  master_id_t master_sel_rd, master_sel_wr;

  addr_t [NUM_MASTER-1:0] master_araddr_pack;
  logic  [NUM_MASTER-1:0] master_rready_pack;

  addr_t [NUM_MASTER-1:0] master_awaddr_pack;
  data_t [NUM_MASTER-1:0] master_wdata_pack;
  strb_t [NUM_MASTER-1:0] master_wstrb_pack;
  logic  [NUM_MASTER-1:0] master_wvalid_pack;
  logic  [NUM_MASTER-1:0] master_bready_pack;

  addr_t master_araddr;
  logic  master_arready;
  data_t master_rdata;
  resp_t master_rresp;
  logic  master_rvalid;
  logic  master_rready;

  addr_t master_awaddr;
  logic  master_awready;
  data_t master_wdata;
  strb_t master_wstrb;
  logic  master_wvalid;
  logic  master_wready;
  resp_t master_bresp;
  logic  master_bvalid;
  logic  master_bready;

  for (genvar i = 0; i < NUM_MASTER; i++) begin
    assign master_araddr_pack[i]   = master[i].ar_addr;
    assign master[i].ar_ready      = master_arready && (i == master_sel_rd);
    assign master[i].r_data        = master_rdata;
    assign master[i].r_resp        = master_rresp;
    assign master[i].r_valid       = master_rvalid && (i == master_sel_rd);
    assign master_rready_pack[i]   = master[i].r_ready;

    assign master_awaddr_pack[i]   = master[i].aw_addr;
    assign master[i].aw_ready      = master_awready && (i == master_sel_wr);
    assign master_wdata_pack[i]    = master[i].w_data;
    assign master_wstrb_pack[i]    = master[i].w_strb;
    assign master_wvalid_pack[i]   = master[i].w_valid;
    assign master[i].w_ready       = master_wready && (i == master_sel_wr);
    assign master[i].b_resp        = master_bresp;
    assign master_bready_pack[i]   = master[i].b_ready;
    assign master[i].b_valid       = master_bvalid && (i == master_sel_wr);
  end

  assign master_araddr  = master_araddr_pack  [master_sel_rd];
  assign master_rready  = master_rready_pack  [master_sel_rd];

  assign master_awaddr  = master_awaddr_pack  [master_sel_wr];
  assign master_wdata   = master_wdata_pack   [master_sel_wr];
  assign master_wstrb   = master_wstrb_pack   [master_sel_wr];
  assign master_wvalid  = master_wvalid_pack  [master_sel_wr];
  assign master_bready  = master_bready_pack  [master_sel_wr];



  slave_id_t slave_sel_rd, slave_sel_wr;

  logic  [NUM_SLAVE-1:0] slave_arready_pack;
  data_t [NUM_SLAVE-1:0] slave_rdata_pack;
  resp_t [NUM_SLAVE-1:0] slave_rresp_pack;
  logic  [NUM_SLAVE-1:0] slave_rvalid_pack;

  logic  [NUM_SLAVE-1:0] slave_awready_pack;
  logic  [NUM_SLAVE-1:0] slave_wready_pack;
  resp_t [NUM_SLAVE-1:0] slave_bresp_pack;
  logic  [NUM_SLAVE-1:0] slave_bvalid_pack;

  addr_t slave_araddr;
  logic  slave_arvalid;
  logic  slave_arready;
  data_t slave_rdata;
  resp_t slave_rresp;
  logic  slave_rvalid;
  logic  slave_rready;

  addr_t slave_awaddr;
  logic  slave_awvalid;
  logic  slave_awready;
  data_t slave_wdata;
  strb_t slave_wstrb;
  logic  slave_wvalid;
  logic  slave_wready;
  resp_t slave_bresp;
  logic  slave_bvalid;
  logic  slave_bready;

  for (genvar i = 0; i < NUM_SLAVE; i++) begin
    assign slave[i].ar_addr      = slave_araddr;
    assign slave[i].ar_valid     = slave_arvalid && (i == slave_sel_rd);
    assign slave_arready_pack[i] = slave[i].ar_ready;
    assign slave_rdata_pack[i]   = slave[i].r_data;
    assign slave_rresp_pack[i]   = slave[i].r_resp;
    assign slave_rvalid_pack[i]  = slave[i].r_valid;
    assign slave[i].r_ready      = slave_rready && (i == slave_sel_rd);

    assign slave[i].aw_addr      = slave_awaddr;
    assign slave[i].aw_valid     = slave_awvalid && (i == slave_sel_wr);
    assign slave_awready_pack[i] = slave[i].aw_ready;
    assign slave[i].w_data       = slave_wdata;
    assign slave[i].w_strb       = slave_wstrb;
    assign slave[i].w_valid      = slave_wvalid && (i == slave_sel_wr);
    assign slave_wready_pack[i]  = slave[i].w_ready;
    assign slave_bresp_pack[i]   = slave[i].b_resp;
    assign slave_bvalid_pack[i]  = slave[i].b_valid;
    assign slave[i].b_ready      = slave_bready && (i == slave_sel_wr);
  end

  assign slave_arready = slave_arready_pack [slave_sel_rd];
  assign slave_rdata   = slave_rdata_pack   [slave_sel_rd];
  assign slave_rresp   = slave_rresp_pack   [slave_sel_rd];
  assign slave_rvalid  = slave_rvalid_pack  [slave_sel_rd];

  assign slave_awready = slave_awready_pack [slave_sel_wr];
  assign slave_wready  = slave_wready_pack  [slave_sel_wr];
  assign slave_bresp   = slave_bresp_pack   [slave_sel_wr];
  assign slave_bvalid  = slave_bvalid_pack  [slave_sel_wr];



  for (genvar i = 0; i < NUM_MASTER; i++) begin
    assign arb_rd.in_req[i] = master[i].ar_valid;
    assign arb_wr.in_req[i] = master[i].aw_valid;
  end


  addr_t rd_resolve_addr, wr_resolve_addr;
  logic [$clog2(NUM_SLAVE)-1:0] rd_match_idx, wr_match_idx;
  logic rd_match_ok, wr_match_ok;

  axi_address_resolver #(
    .ADDR_WIDTH( ADDR_WIDTH ),
    .NUM_SLAVE ( NUM_SLAVE  ),
    .NUM_RULES ( NUM_RULES  )
  ) i_rd_resolver (
    .rules       ( rules           ),
    .addr_i      ( rd_resolve_addr ),
    .match_idx_o ( rd_match_idx    ),
    .match_ok_o  ( rd_match_ok     )
  );

  axi_address_resolver #(
    .ADDR_WIDTH( ADDR_WIDTH ),
    .NUM_SLAVE ( NUM_SLAVE  ),
    .NUM_RULES ( NUM_RULES  )
  ) i_wr_resolver (
    .rules       ( rules           ),
    .addr_i      ( wr_resolve_addr ),
    .match_idx_o ( wr_match_idx    ),
    .match_ok_o  ( wr_match_ok     )
  );


  always_comb begin
    state_rd_d      = state_rd_q;
    tag_rd_d        = tag_rd_q;

    arb_rd.out_ack  = 0;
    master_sel_rd   = tag_rd_q.master;
    slave_sel_rd    = tag_rd_q.slave;
    rd_resolve_addr = master_araddr;

    slave_araddr    = master_araddr;
    slave_arvalid   = 0;
    master_arready  = 0;
    master_rdata    = slave_rdata;
    master_rresp    = slave_rresp;
    master_rvalid   = 0;
    slave_rready    = 0;

    case (state_rd_q)
      RD_IDLE: begin
        master_sel_rd = arb_rd.out_sel;
        if (arb_rd.out_req) begin
          arb_rd.out_ack  = 1;
          tag_rd_d.master = arb_rd.out_sel;
          state_rd_d      = RD_REQ;
        end
      end

      RD_REQ: begin
        slave_sel_rd   = rd_match_idx;
        tag_rd_d.slave = rd_match_idx;


        if (rd_match_ok) begin
          slave_arvalid = 1;
          if (slave_arready) begin
            state_rd_d     = RD_RESP;
            master_arready = 1;
          end
        end else begin
          state_rd_d     = RD_ERR_RESP;
          master_arready = 1;
        end
      end

      RD_RESP: begin
        master_rvalid = slave_rvalid;
        slave_rready = master_rready;
        if (slave_rvalid && master_rready) begin
          state_rd_d = RD_IDLE;
        end
      end


      RD_ERR_RESP: begin
        master_rresp  = axi_pkg::RESP_DECERR;
        master_rvalid = 1;
        if (master_rready) begin
          state_rd_d = RD_IDLE;
        end
      end

      default: state_rd_d = RD_IDLE;
    endcase
  end


  always_comb begin
    state_wr_d = state_wr_q;
    tag_wr_d   = tag_wr_q;

    arb_wr.out_ack  = 0;
    master_sel_wr   = tag_wr_q.master;
    slave_sel_wr    = tag_wr_q.slave;
    wr_resolve_addr = master_awaddr;

    slave_awaddr    = master_awaddr;
    slave_awvalid   = 0;
    master_awready  = 0;
    slave_wdata     = master_wdata;
    slave_wstrb     = master_wstrb;
    slave_wvalid    = 0;
    master_wready   = 0;
    master_bresp    = slave_bresp;
    master_bvalid   = 0;
    slave_bready    = 0;

    case (state_wr_q)
      WR_IDLE: begin
        master_sel_wr = arb_wr.out_sel;
        if (arb_wr.out_req) begin
          arb_wr.out_ack  = 1;
          tag_wr_d.master = arb_wr.out_sel;
          state_wr_d      = WR_REQ;
        end
      end

      WR_REQ: begin
        slave_sel_wr   = wr_match_idx;
        tag_wr_d.slave = wr_match_idx;


        if (wr_match_ok) begin
          slave_awvalid = 1;
          if (slave_awready) begin
            state_wr_d     = WR_DATA;
            master_awready = 1;
          end
        end else begin
          state_wr_d     = WR_ERR_DATA;
          master_awready = 1;
        end
      end

      WR_DATA: begin
        master_wready = slave_wready;
        slave_wvalid = master_wvalid;
        if (slave_wvalid && master_wready) begin
          state_wr_d = WR_RESP;
        end
      end

      WR_RESP: begin
        master_bvalid = slave_bvalid;
        slave_bready = master_bready;
        if (slave_bvalid && master_bready) begin
          state_wr_d = WR_IDLE;
        end
      end


      WR_ERR_DATA: begin
        master_wready = 1;
        if (master_wvalid) begin
          state_wr_d = WR_ERR_RESP;
        end
      end


      WR_ERR_RESP: begin
        master_bresp  = axi_pkg::RESP_DECERR;
        master_bvalid = 1;
        if (master_bready) begin
          state_wr_d = WR_IDLE;
        end
      end

      default: state_wr_d = WR_IDLE;
    endcase
  end

endmodule