// 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 aon_timer_env_pkg::*;
  import aon_timer_test_pkg::*;

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

  wire                          clk, rst_n;
  wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
  wire                          clk_aon, rst_aon_n;
  wire                          lc_escalate_en_bit;
  lc_ctrl_pkg::lc_tx_t          lc_escalate_en;
  wire                          wkup_expired, wdog_bark;
  wire                          wkup_req, rst_req;
  wire                          sleep;

  clk_rst_if fast_clk_rst_if(.clk(clk),     .rst_n(rst_n));
  clk_rst_if aon_clk_rst_if (.clk(clk_aon), .rst_n(rst_aon_n));

  tl_if tl_if(.clk(clk), .rst_n(rst_n));

  // An input to the DUT that shows whether the CPU is enabled. Rather than wire up an interface
  // with an lc_tx_t member, we expose lc_escalate_en as a single bit and translate it to the right
  // type here.
  pins_if #(1) lc_escalate_en_if (lc_escalate_en_bit);
  assign lc_escalate_en = lc_escalate_en_bit ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off;

  // The interrupts that are in the fast clock domain
  pins_if #(NUM_MAX_INTERRUPTS) fast_intr_if(interrupts);
  assign interrupts[0] = wkup_expired;
  assign interrupts[1] = wdog_bark;

  // The interrupts in the slow clock domain
  pins_if #(2) aon_intr_if({wkup_req, rst_req});

  // An input to the DUT that shows whether we are in sleep mode
  pins_if #(1) sleep_if (sleep);

 `DV_ALERT_IF_CONNECT

  aon_timer dut (
    .clk_i                     (clk),
    .rst_ni                    (rst_n),
    .clk_aon_i                 (clk_aon),
    .rst_aon_ni                (rst_aon_n),
    .tl_i                      (tl_if.h2d),
    .tl_o                      (tl_if.d2h),
    .alert_rx_i                (alert_rx),
    .alert_tx_o                (alert_tx),
    .lc_escalate_en_i          (lc_escalate_en),
    .intr_wkup_timer_expired_o (wkup_expired),
    .intr_wdog_timer_bark_o    (wdog_bark),
    .nmi_wdog_timer_bark_o     (/*TODO*/),
    .wkup_req_o                (wkup_req),
    .aon_timer_rst_req_o       (rst_req),
    .sleep_mode_i              (sleep)
  );

  initial begin
    // Configure interfaces
    fast_clk_rst_if.set_active();
    aon_clk_rst_if.set_active();
    aon_clk_rst_if.set_freq_khz(200);

    lc_escalate_en_if.drive_en('1);
    sleep_if.drive_en('1);

    uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", fast_clk_rst_if);
    uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "aon_clk_rst_vif", aon_clk_rst_if);
    uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent*", "vif", tl_if);

    uvm_config_db#(virtual pins_if #(1))::set(null, "*.env", "lc_escalate_en_vif",
                                              lc_escalate_en_if);
    uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", fast_intr_if);
    uvm_config_db#(virtual pins_if #(2))::set(null, "*.env", "aon_intr_vif", aon_intr_if);
    uvm_config_db#(virtual pins_if #(1))::set(null, "*.env", "sleep_vif", sleep_if);

    $timeformat(-12, 0, " ps", 12);
    run_test();
  end

endmodule
