// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// xbar_${xbar.name} module generated by `tlgen.py` tool
// all reset signals should be generated from one reset signal to not make any deadlock
//
// Interconnect
% for host in xbar.hosts:
${xbar.repr_tree(host, 0)}
% endfor

module xbar_${xbar.name} (
% for clock in xbar.clocks:
  input clk_${clock}_i,
  input rst_${clock}_ni,
% endfor

  // Host interfaces
% for node in xbar.hosts:
  input  tlul_pkg::tl_h2d_t tl_${node.name}_i,
  output tlul_pkg::tl_d2h_t tl_${node.name}_o,
% endfor

  // Device interfaces
% for node in xbar.devices:
  output tlul_pkg::tl_h2d_t tl_${node.name}_o,
  input  tlul_pkg::tl_d2h_t tl_${node.name}_i,
% endfor

  input scanmode_i
);

  import tlul_pkg::*;
  import tl_${xbar.name}_pkg::*;

% for block in xbar.nodes:
  ## Create enum type for Upstream and Downstream ports connection
  % if block.node_type.name   == "ASYNC_FIFO":
    ## One US, one DS
  tl_h2d_t tl_${block.name}_us_h2d ;
  tl_d2h_t tl_${block.name}_us_d2h ;
  tl_h2d_t tl_${block.name}_ds_h2d ;
  tl_d2h_t tl_${block.name}_ds_d2h ;

  % elif block.node_type.name == "SOCKET_1N":
    ## One US, multiple DS
  tl_h2d_t tl_${block.name}_us_h2d ;
  tl_d2h_t tl_${block.name}_us_d2h ;

  ##typedef enum int {
  ##  % for port in block.ds:
  ##    % if loop.last:
  ##    % else:
  ##    % endif
  ##  % endfor
  ##} socket_${block.name}_ds_e;

  tl_h2d_t tl_${block.name}_ds_h2d [${len(block.ds)}];
  tl_d2h_t tl_${block.name}_ds_d2h [${len(block.ds)}];

  // Create steering signal
  logic [${len(block.ds).bit_length()-1}:0] dev_sel_${block.name};

  % elif block.node_type.name == "SOCKET_M1":
    ## Multiple US, one DS
    ## typedef enum int {
    ##   % for port in block.us:
    ##     % if loop.last:
    ##     % else:
    ##     % endif
    ##   % endfor
    ## } socket_${block.name}_us_e;

  tl_h2d_t tl_${block.name}_us_h2d [${len(block.us)}];
  tl_d2h_t tl_${block.name}_us_d2h [${len(block.us)}];

  tl_h2d_t tl_${block.name}_ds_h2d ;
  tl_d2h_t tl_${block.name}_ds_d2h ;

  % else:
    ## block is either HOST or DEVICE. Ignore
  % endif
% endfor

% for conn in xbar.edges:
  ## sweep each entry of edges and find each end (us, ds) then connect between
  ## Connect upstream
<%
    if conn.ds.node_type.name == "ASYNC_FIFO":
      ds_h2d_name = 'tl_' + conn.ds.name + '_us_h2d'
      ds_d2h_name = 'tl_' + conn.ds.name + '_us_d2h'
      ds_index = -1
    elif conn.ds.node_type.name == "SOCKET_1N":
      ds_h2d_name = 'tl_' + conn.ds.name + '_us_h2d'
      ds_d2h_name = 'tl_' + conn.ds.name + '_us_d2h'
      ds_index = -1
    elif conn.ds.node_type.name == "SOCKET_M1":
      ds_h2d_name = 'tl_' + conn.ds.name + '_us_h2d'
      ds_d2h_name = 'tl_' + conn.ds.name + '_us_d2h'
      ds_index = conn.ds.us.index(conn)
    elif conn.ds.node_type.name == "DEVICE":
      ds_h2d_name = 'tl_' + conn.ds.name + '_o'
      ds_d2h_name = 'tl_' + conn.ds.name + '_i'
      ds_index = -1

    if conn.us.node_type.name == "ASYNC_FIFO":
      us_h2d_name = 'tl_' + conn.us.name + '_ds_h2d'
      us_d2h_name = 'tl_' + conn.us.name + '_ds_d2h'
      us_index = -1
    elif conn.us.node_type.name == "SOCKET_1N":
      us_h2d_name = 'tl_' + conn.us.name + '_ds_h2d'
      us_d2h_name = 'tl_' + conn.us.name + '_ds_d2h'
      us_index = conn.us.ds.index(conn)
    elif conn.us.node_type.name == "SOCKET_M1":
      us_h2d_name = 'tl_' + conn.us.name + '_ds_h2d'
      us_d2h_name = 'tl_' + conn.us.name + '_ds_d2h'
      us_index = -1
    elif conn.us.node_type.name == "HOST":
      us_h2d_name = 'tl_' + conn.us.name + '_i'
      us_d2h_name = 'tl_' + conn.us.name + '_o'
      us_index = -1
%>\

% if us_index == -1 and ds_index == -1:
  assign ${ds_h2d_name} = ${us_h2d_name};
  assign ${us_d2h_name} = ${ds_d2h_name};
% elif us_index == -1 and ds_index != -1:
  assign ${ds_h2d_name}[${ds_index}] = ${us_h2d_name};
  assign ${us_d2h_name} = ${ds_d2h_name}[${ds_index}];
% elif us_index != -1 and ds_index == -1:
  assign ${ds_h2d_name} = ${us_h2d_name}[${us_index}];
  assign ${us_d2h_name}[${us_index}] = ${ds_d2h_name};
% else:
  assign ${ds_h2d_name}[${ds_index}] = ${us_h2d_name}[${us_index}];
  assign ${us_d2h_name}[${us_index}] = ${ds_d2h_name}[${ds_index}];
% endif
% endfor

% for block in xbar.socket_1ns:
<%
  addr_sig = "tl_" + block.name + "_us_h2d.a_address"
  sel_len = len(block.ds).bit_length()
%>\
  always_comb begin
    // default steering to generate error response if address is not within the range
    dev_sel_${block.name} = ${"%d'd%d" % (sel_len, len(block.ds))};
% for i in block.ds:
<%
  leaf = xbar.get_leaf_from_s1n(block, loop.index);
  name_space = "ADDR_SPACE_" + leaf.name.upper();
  name_mask  = "ADDR_MASK_" + leaf.name.upper();
%>\
  % if loop.first:
    if ((${addr_sig} & ~(${name_mask})) == ${name_space}) begin
  % else:
    end else if ((${addr_sig} & ~(${name_mask})) == ${name_space}) begin
  % endif
      dev_sel_${block.name} = ${"%d'd%d" % (sel_len, loop.index)};
  % if loop.last:
    end
  % endif
% endfor
  end

% endfor

  // Instantiation phase
% for block in xbar.nodes:
  % if block.node_type.name   == "ASYNC_FIFO":
  tlul_fifo_async #(
    .ReqDepth        (3),// At least 3 to make async work
    .RspDepth        (3) // At least 3 to make async work
  ) u_${block.name} (
    .clk_h_i      (clk_${block.clocks[0]}_i),
    .rst_h_ni     (rst_${block.clocks[0]}_ni),
    .clk_d_i      (clk_${block.clocks[1]}_i),
    .rst_d_ni     (rst_${block.clocks[1]}_ni),
    .tl_h_i       (tl_${block.name}_us_h2d),
    .tl_h_o       (tl_${block.name}_us_d2h),
    .tl_d_o       (tl_${block.name}_ds_h2d),
    .tl_d_i       (tl_${block.name}_ds_d2h)
  );
  % elif block.node_type.name == "SOCKET_1N":
  tlul_socket_1n #(
    % if block.hpass != 1:
    .HReqPass (1'b${block.hpass}),
    .HRspPass (1'b${block.hpass}),
    % endif
    % if block.dpass != 2**(len(block.ds)) -1:
    .DReqPass (${len(block.ds)}'h ${"%x" % block.dpass}),
    .DRspPass (${len(block.ds)}'h ${"%x" % block.dpass}),
    % endif
    ## //.HReqDepth(),
    ## //.HRspDepth(),
    ## //.DReqDepth(),
    ## //.DRspDepth(),
    .N        (${len(block.ds)})
  ) u_${block.name} (
    .clk_i        (clk_${xbar.clock}_i),
    .rst_ni       (rst_${xbar.clock}_ni),
    .tl_h_i       (tl_${block.name}_us_h2d),
    .tl_h_o       (tl_${block.name}_us_d2h),
    .tl_d_o       (tl_${block.name}_ds_h2d),
    .tl_d_i       (tl_${block.name}_ds_d2h),
    .dev_select   (dev_sel_${block.name})
  );
  % elif block.node_type.name == "SOCKET_M1":
  tlul_socket_m1 #(
    % if block.hpass != 2**(len(block.us)) -1:
    .HReqPass     (${len(block.us)}'h ${"%x" % block.hpass}),
    .HRspPass     (${len(block.us)}'h ${"%x" % block.hpass}),
    % endif
    ## //.HReqDepth    (),
    ## //.HRspDepth    (),
    % if block.dpass != 1:
    .DReqPass     (1'b${block.dpass}),
    .DRspPass     (1'b${block.dpass}),
    % endif
    ## //.DReqDepth    (),
    ## //.DRspDepth    (),
    .M            (${len(block.us)})
  ) u_${block.name} (
    .clk_i        (clk_${xbar.clock}_i),
    .rst_ni       (rst_${xbar.clock}_ni),
    .tl_h_i       (tl_${block.name}_us_h2d),
    .tl_h_o       (tl_${block.name}_us_d2h),
    .tl_d_o       (tl_${block.name}_ds_h2d),
    .tl_d_i       (tl_${block.name}_ds_d2h)
  );
  % endif
% endfor

endmodule
