// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
module tb;
  // dep packages
  import uvm_pkg::*;
  import dv_utils_pkg::*;
  import ${name}_env_pkg::*;
  import ${name}_test_pkg::*;

  // macro includes
  `include "uvm_macros.svh"
  `include "dv_macros.svh"

  wire clk, rst_n;
% if is_cip:
% if has_interrupts:
  wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
% endif
% if has_alerts:
  // TODO: change alert_names
  list_of_alerts = {"alert_names"};
% endif
% endif

  // interfaces
  clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n));
% if is_cip:
% if has_interrupts:
  pins_if #(NUM_MAX_INTERRUPTS) intr_if(interrupts);
% endif
% if has_alerts:
  // TODO: declare alert interfaces according to the list_of_alerts
  alert_if alert_names(.clk(clk), .rst_n(rst_n))
% endif
  pins_if #(1) devmode_if();
  tl_if tl_if(.clk(clk), .rst_n(rst_n));
% endif
% for agent in env_agents:
  ${agent}_if ${agent}_if();
% endfor

  // dut
  ${name} dut (
    .clk_i                (clk        ),
% if is_cip:
    .rst_ni               (rst_n      ),

    .tl_i                 (tl_if.h2d  ),
% if has_alerts:
    .tl_o                 (tl_if.d2h  ),
    .alert_rx_i           (alert_names.alert_rx ),
    .alert_tx_o           (alert_names.alert_tx )
% else:
    .tl_o                 (tl_if.d2h  )
% endif
% else:
    .rst_ni               (rst_n      )

% endif
    // TODO: add remaining IOs and hook them
  );

  initial begin
    // drive clk and rst_n from clk_if
    clk_rst_if.set_active();
    uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if);
% if is_cip:
% if has_interrupts:
    uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if);
% endif
% if has_alerts:
  // TODO: set alert interfaces with the correct names
  uvm_config_db#(virtual alert_if)::set(null, "*.env.m_alert_agent_alert_names",
        "vif", alert_names);
% endif
    uvm_config_db#(devmode_vif)::set(null, "*.env", "devmode_vif", devmode_if);
    uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if);
% endif
% for agent in env_agents:
    uvm_config_db#(virtual ${agent}_if)::set(null, "*.env.m_${agent}_agent*", "vif", ${agent}_if);
% endfor
    $timeformat(-12, 0, " ps", 12);
    run_test();
  end

endmodule
