module reg_mux #(
  parameter int unsigned NoPorts = 32'd0,
  parameter int unsigned AW = 0,
  parameter int unsigned DW = 0,
  parameter type req_t = logic,
  parameter type rsp_t = logic
) (
  input  logic               clk_i,
  input  logic               rst_ni,
  input  req_t [NoPorts-1:0] in_req_i,
  output rsp_t [NoPorts-1:0] in_rsp_o,
  output req_t               out_req_o,
  input  rsp_t               out_rsp_i
);

  logic [NoPorts-1:0] in_valid, in_ready;
  `REG_BUS_TYPEDEF_REQ(req_payload_t, logic [AW-1:0], logic [DW-1:0], logic [DW/8-1:0])

  req_payload_t [NoPorts-1:0] in_payload;
  req_payload_t out_payload;

  for (genvar i = 0; i < NoPorts; i++) begin : gen_unpack
    // Request
    assign in_valid[i] = in_req_i[i].valid;
    assign in_payload[i].addr = in_req_i[i].addr;
    assign in_payload[i].write = in_req_i[i].write;
    assign in_payload[i].wdata = in_req_i[i].wdata;
    assign in_payload[i].wstrb = in_req_i[i].wstrb;
    assign in_payload[i].valid = in_req_i[i].valid;
    // Response
    assign in_rsp_o[i].ready = in_ready[i];
    assign in_rsp_o[i].rdata = out_rsp_i.rdata;
    assign in_rsp_o[i].error = out_rsp_i.error;
  end

  stream_arbiter #(
    .DATA_T (req_payload_t),
    .N_INP (NoPorts)
  ) i_stream_arbiter (
    .clk_i,
    .rst_ni,
    .inp_data_i (in_payload),
    .inp_valid_i (in_valid),
    .inp_ready_o (in_ready),
    .oup_data_o (out_payload),
    .oup_valid_o (out_req_o.valid),
    .oup_ready_i (out_rsp_i.ready)
  );

  assign out_req_o.addr = out_payload.addr;
  assign out_req_o.write = out_payload.write;
  assign out_req_o.wdata = out_payload.wdata;
  assign out_req_o.wstrb = out_payload.wstrb;
  assign out_req_o.valid = out_payload.valid;

endmodule