
// TL-UL socket M:1 module
//
// Verilog parameters
//   M:             Number of host ports.
//   HReqPass:      M bit array to allow requests to pass through the host i
//                  FIFO with no clock delay if the request FIFO is empty. If
//                  1'b0, at least one clock cycle of latency is created.
//                  Default is 1'b1.
//   HRspPass:      Same as HReqPass but for host response FIFO.
//   HReqDepth:     Mx4 bit array. bit[i*4+:4] is depth of host i request FIFO.
//                  Depth of zero is allowed if ReqPass is true. A maximum value
//                  of 16 is allowed, default is 2.
//   HRspDepth:     Same as HReqDepth but for host response FIFO.
//   DReqPass:      Same as HReqPass but for device request FIFO.
//   DRspPass:      Same as HReqPass but for device response FIFO.
//   DReqDepth:     Same as HReqDepth but for device request FIFO.
//   DRspDepth:     Same as HReqDepth but for device response FIFO.

module tlul_socket_m1 #(
  parameter int unsigned  M         = 4,
  parameter bit [M-1:0]   HReqPass  = {M{1'b1}},
  parameter bit [M-1:0]   HRspPass  = {M{1'b1}},
  parameter bit [M*4-1:0] HReqDepth = {M{4'h2}},
  parameter bit [M*4-1:0] HRspDepth = {M{4'h2}},
  parameter bit           DReqPass  = 1'b1,
  parameter bit           DRspPass  = 1'b1,
  parameter bit [3:0]     DReqDepth = 4'h2,
  parameter bit [3:0]     DRspDepth = 4'h2
) (
  input                     clk_i,
  input                     rst_ni,

  input  tlul_pkg::tl_h2d_t tl_h_i [M],
  output tlul_pkg::tl_d2h_t tl_h_o [M],

  output tlul_pkg::tl_h2d_t tl_d_o,
  input  tlul_pkg::tl_d2h_t tl_d_i
);

  // Signals
  //
  //  tl_h_i/o[0] |  tl_h_i/o[1] | ... |  tl_h_i/o[M-1]
  //      |              |                    |
  // u_hostfifo[0]  u_hostfifo[1]        u_hostfifo[M-1]
  //      |              |                    |
  //       hreq_fifo_o(i) / hrsp_fifo_i(i)
  //     ---------------------------------------
  //     |       request/grant/req_data        |
  //     |                                     |
  //     |           PRIM_ARBITER              |
  //     |                                     |
  //     |  arb_valid / arb_ready / arb_data   |
  //     ---------------------------------------
  //                     |
  //                dreq_fifo_i / drsp_fifo_o
  //                     |
  //                u_devicefifo
  //                     |
  //                  tl_d_o/i
  //
  // Required ID width to distinguish between host ports
  //  Used in response steering
  localparam int unsigned IDW   = tlul_pkg::TL_AIW;
  localparam int unsigned STIDW = $clog2(M);

  tlul_pkg::tl_h2d_t hreq_fifo_o [M];
  tlul_pkg::tl_d2h_t hrsp_fifo_i [M];

  logic [M-1:0] hrequest;
  logic [M-1:0] hgrant;

  tlul_pkg::tl_h2d_t dreq_fifo_i;
  tlul_pkg::tl_d2h_t drsp_fifo_o;

  logic arb_valid;
  logic arb_ready;
  tlul_pkg::tl_h2d_t arb_data;

  // Host Req/Rsp FIFO
  for (genvar i = 0 ; i < M ; i++) begin : gen_host_fifo
    tlul_pkg::tl_h2d_t hreq_fifo_i;

    // ID Shifting
    logic [STIDW-1:0] reqid_sub;
    logic [IDW-1:0] shifted_id;
    assign reqid_sub = i;   // can cause conversion error?
    assign shifted_id = {
      tl_h_i[i].a_source[0+:(IDW-STIDW)],
      reqid_sub
    };

 
    // assign not connected bits to nc_* signal to make lint happy
    logic [IDW-1 : IDW-STIDW] unused_tl_h_source;
    assign unused_tl_h_source = tl_h_i[i].a_source[IDW-1 -: STIDW];

    // Put shifted ID
    assign hreq_fifo_i = '{
      a_valid:    tl_h_i[i].a_valid,
      a_opcode:   tl_h_i[i].a_opcode,
      a_param:    tl_h_i[i].a_param,
      a_size:     tl_h_i[i].a_size,
      a_source:   shifted_id,
      a_address:  tl_h_i[i].a_address,
      a_mask:     tl_h_i[i].a_mask,
      a_data:     tl_h_i[i].a_data,
      d_ready:    tl_h_i[i].d_ready
    };

    tlul_fifo_sync #(
      .ReqPass    (HReqPass[i]),
      .RspPass    (HRspPass[i]),
      .ReqDepth   (HReqDepth[i*4+:4]),
      .RspDepth   (HRspDepth[i*4+:4]),
      .SpareReqW  (1)
    ) u_hostfifo (
      .clk_i,
      .rst_ni,
      .tl_h_i      (hreq_fifo_i),
      .tl_h_o      (tl_h_o[i]),
      .tl_d_o      (hreq_fifo_o[i]),
      .tl_d_i      (hrsp_fifo_i[i]),
      .spare_req_i (1'b0),
      .spare_req_o (),
      .spare_rsp_i (1'b0),
      .spare_rsp_o ()
    );
  end

  // Device Req/Rsp FIFO
  tlul_fifo_sync #(
    .ReqPass    (DReqPass),
    .RspPass    (DRspPass),
    .ReqDepth   (DReqDepth),
    .RspDepth   (DRspDepth),
    .SpareReqW  (1)
  ) u_devicefifo (
    .clk_i,
    .rst_ni,
    .tl_h_i      (dreq_fifo_i),
    .tl_h_o      (drsp_fifo_o),
    .tl_d_o      (tl_d_o),
    .tl_d_i      (tl_d_i),
    .spare_req_i (1'b0),
    .spare_req_o (),
    .spare_rsp_i (1'b0),
    .spare_rsp_o ()
  );

  // Request Arbiter
  for (genvar i = 0 ; i < M ; i++) begin : gen_arbreqgnt
    assign hrequest[i] = hreq_fifo_o[i].a_valid;
  end

  assign arb_ready = drsp_fifo_o.a_ready;

  if (tlul_pkg::ArbiterImpl == "PPC") begin : gen_arb_ppc
    prim_arbiter_ppc #(
      .N          (M),
      .DW         ($bits(tlul_pkg::tl_h2d_t)),
      .EnReqStabA (0)
    ) u_reqarb (
      .clk_i,
      .rst_ni,
      .req_i   ( hrequest    ),
      .data_i  ( hreq_fifo_o ),
      .gnt_o   ( hgrant      ),
      .idx_o   (             ),
      .valid_o ( arb_valid   ),
      .data_o  ( arb_data    ),
      .ready_i ( arb_ready   )
    );
  end else if (tlul_pkg::ArbiterImpl == "BINTREE") begin : gen_tree_arb
    prim_arbiter_tree #(
      .N          (M),
      .DW         ($bits(tlul_pkg::tl_h2d_t)),
      .EnReqStabA (0)
    ) u_reqarb (
      .clk_i,
      .rst_ni,
      .req_i   ( hrequest    ),
      .data_i  ( hreq_fifo_o ),
      .gnt_o   ( hgrant      ),
      .idx_o   (             ),
      .valid_o ( arb_valid   ),
      .data_o  ( arb_data    ),
      .ready_i ( arb_ready   )
    );
  end else begin : gen_unknown
    
  end

  logic [  M-1:0] hfifo_rspvalid;
  logic [  M-1:0] dfifo_rspready;
  logic [IDW-1:0] hfifo_rspid;
  logic dfifo_rspready_merged;

  // arb_data --> dreq_fifo_i
  //   dreq_fifo_i.hd_rspready <= dfifo_rspready

  assign dfifo_rspready_merged = |dfifo_rspready;
  assign dreq_fifo_i = '{
    a_valid:   arb_valid,
    a_opcode:  arb_data.a_opcode,
    a_param:   arb_data.a_param,
    a_size:    arb_data.a_size,
    a_source:  arb_data.a_source,
    a_address: arb_data.a_address,
    a_mask:    arb_data.a_mask,
    a_data:    arb_data.a_data,

    d_ready:   dfifo_rspready_merged
  };

  // Response ID steering
  // drsp_fifo_o --> hrsp_fifo_i[i]

  // Response ID shifting before put into host fifo
  assign hfifo_rspid = {
    {STIDW{1'b0}},
    drsp_fifo_o.d_source[IDW-1:STIDW]
  };
  for (genvar i = 0 ; i < M ; i++) begin : gen_idrouting
    assign hfifo_rspvalid[i] = drsp_fifo_o.d_valid &
                               (drsp_fifo_o.d_source[0+:STIDW] == i);
    assign dfifo_rspready[i] = hreq_fifo_o[i].d_ready                &
                               (drsp_fifo_o.d_source[0+:STIDW] == i) &
                              drsp_fifo_o.d_valid;

    assign hrsp_fifo_i[i] = '{
      d_valid:  hfifo_rspvalid[i],
      d_opcode: drsp_fifo_o.d_opcode,
      d_param:  drsp_fifo_o.d_param,
      d_size:   drsp_fifo_o.d_size,
      d_source: hfifo_rspid,
      d_sink:   drsp_fifo_o.d_sink,
      d_data:   drsp_fifo_o.d_data,
      d_error:  drsp_fifo_o.d_error,
      a_ready:  hgrant[i]
    };
  end


endmodule
