// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// tb__xbar_connect generated by `topgen.py` tool
<%
from collections import OrderedDict
import topgen.lib as lib

top_hier = 'tb.dut.top_' + top["name"] + '.'
clk_hier = top_hier + top["clocks"].hier_paths["top"]

clk_src = OrderedDict()
for xbar in top["xbar"]:
  for clk, src in xbar["clock_srcs"].items():
    clk_src[clk] = src

clk_freq = OrderedDict()
for clock in top["clocks"].all_srcs.values():
  if clock.name in clk_src.values():
    clk_freq[clock.name] = clock.freq

hosts = OrderedDict()
devices = OrderedDict()
for xbar in top["xbar"]:
  for node in xbar["nodes"]:
    if node["type"] == "host" and not node["xbar"]:
      hosts[node["name"]] = "clk_" + clk_src[node["clock"]]
    elif node["type"] == "device" and not node["xbar"]:
      devices[node["name"]] = "clk_" + clk_src[node["clock"]]

def escape_if_name(qual_if_name):
    return qual_if_name.replace('.', '__')

%>\

## Need to use a variable assignment for "\" to bypass the newline filter.
`define DRIVE_CHIP_TL_HOST_IF(tl_name, inst_name, sig_name) ${"\\"}
     force ``tl_name``_tl_if.d2h = dut.top_${top["name"]}.u_``inst_name``.``sig_name``_i; ${"\\"}
     force dut.top_${top["name"]}.u_``inst_name``.``sig_name``_o = ``tl_name``_tl_if.h2d; ${"\\"}
     force dut.top_${top["name"]}.u_``inst_name``.clk_i = 0; ${"\\"}
     uvm_config_db#(virtual tl_if)::set(null, $sformatf("*env.%0s_agent", `"tl_name`"), "vif", ${"\\"}
                                        ``tl_name``_tl_if);

`define DRIVE_CHIP_TL_DEVICE_IF(tl_name, inst_name, sig_name) ${"\\"}
     force ``tl_name``_tl_if.h2d = dut.top_${top["name"]}.u_``inst_name``.``sig_name``_i; ${"\\"}
     force dut.top_${top["name"]}.u_``inst_name``.``sig_name``_o = ``tl_name``_tl_if.d2h; ${"\\"}
     force dut.top_${top["name"]}.u_``inst_name``.clk_i = 0; ${"\\"}
     uvm_config_db#(virtual tl_if)::set(null, $sformatf("*env.%0s_agent", `"tl_name`"), "vif", ${"\\"}
                                        ``tl_name``_tl_if);

`define DRIVE_CHIP_TL_EXT_DEVICE_IF(tl_name, port_name) ${"\\"}
     force ``tl_name``_tl_if.h2d = dut.top_${top["name"]}.``port_name``_req_o; ${"\\"}
     force dut.top_${top["name"]}.``port_name``_rsp_i = ``tl_name``_tl_if.d2h; ${"\\"}
     uvm_config_db#(virtual tl_if)::set(null, $sformatf("*env.%0s_agent", `"tl_name`"), "vif", ${"\\"}
                                        ``tl_name``_tl_if);

% for c in clk_freq.keys():
wire clk_${c};
clk_rst_if clk_rst_if_${c}(.clk(clk_${c}), .rst_n(rst_n));
% endfor

% for i, clk in hosts.items():
tl_if ${escape_if_name(i)}_tl_if(${clk}, rst_n);
% endfor

% for i, clk in devices.items():
tl_if ${escape_if_name(i)}_tl_if(${clk}, rst_n);
% endfor

initial begin
  bit xbar_mode;
  void'($value$plusargs("xbar_mode=%0b", xbar_mode));
  if (xbar_mode) begin
    // only enable assertions in xbar as many pins are unconnected
    $assertoff(0, tb);
% for xbar in top["xbar"]:
    $asserton(0, tb.dut.top_${top["name"]}.u_xbar_${xbar["name"]});
% endfor

% for c in clk_freq.keys():
    clk_rst_if_${c}.set_active(.drive_rst_n_val(0));
    clk_rst_if_${c}.set_freq_khz(${clk_freq[c]} / 1000);
% endfor

    // bypass clkmgr, force clocks directly
% for xbar in top["xbar"]:
  % for clk, src in xbar["clock_srcs"].items():
    force ${top_hier}u_xbar_${xbar["name"]}.${clk} = clk_${src};
  % endfor
% endfor

    // bypass rstmgr, force resets directly
% for xbar in top["xbar"]:
  % for rst in xbar["reset_connections"]:
    force ${top_hier}u_xbar_${xbar["name"]}.${rst} = rst_n;
  % endfor
% endfor

% for xbar in top["xbar"]:
  % for node in xbar["nodes"]:
<%
clk = 'clk_' + clk_src[node["clock"]]
esc_name = node['name'].replace('.', '__')
inst_sig_list = lib.find_otherside_modules(top, xbar["name"], 'tl_' + esc_name)
inst_name = inst_sig_list[0][1]
sig_name = inst_sig_list[0][2]
%>\
    % if node["type"] == "host" and not node["xbar"]:
    `DRIVE_CHIP_TL_HOST_IF(${esc_name}, ${inst_name}, ${sig_name})
    % elif node["type"] == "device" and not node["xbar"] and node["stub"]:
    `DRIVE_CHIP_TL_EXT_DEVICE_IF(${esc_name}, ${inst_name}_${sig_name})
    % elif node["type"] == "device" and not node["xbar"]:
    `DRIVE_CHIP_TL_DEVICE_IF(${esc_name}, ${inst_name}, ${sig_name})
    % endif
  % endfor
% endfor
  end
end

`undef DRIVE_CHIP_TL_HOST_IF
`undef DRIVE_CHIP_TL_DEVICE_IF
`undef DRIVE_CHIP_TL_EXT_DEVICE_IF
