// 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 aes_env_pkg::*;
  import aes_test_pkg::*;

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

  wire                                    clk, rst_n, rst_shadowed_n;
  wire                                    devmode;
  wire [NUM_MAX_INTERRUPTS-1:0]           interrupts;
  wire                                    edn_req;
  wire [$bits(lc_ctrl_pkg::lc_tx_t) : 0]  lc_escalate;
  wire                                    idle;
  prim_mubi_pkg::mubi4_t                  idle_s;
  lc_ctrl_pkg::lc_tx_t                    lc_escalate_en;
  keymgr_pkg::hw_key_req_t                keymgr_key;

  // interfaces
  clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n));
  rst_shadowed_if rst_shadowed_if(.rst_n(rst_n), .rst_shadowed_n(rst_shadowed_n));
  pins_if #(NUM_MAX_INTERRUPTS) intr_if(interrupts);

  pins_if #(1) devmode_if(devmode);
  pins_if #($bits(lc_escalate)) lc_escalate_if (lc_escalate);
  pins_if #(1) idle_if (idle);
  tl_if tl_if(.clk(clk), .rst_n(rst_n));

  // edn_clk, edn_rst_n and edn_if is defined and driven in below macro
  `DV_EDN_IF_CONNECT
  `DV_ALERT_IF_CONNECT

  key_sideload_if sideload_if(.clk_i(clk), .rst_ni(rst_n));
 //lc_ctrl_pkg::On
  assign lc_escalate_en = lc_escalate[0] ?
                          lc_ctrl_pkg::lc_tx_t'(lc_escalate[$bits(lc_ctrl_pkg::lc_tx_t):1]) :
                          lc_ctrl_pkg::Off;

  assign idle = (idle_s == prim_mubi_pkg::MuBi4True) ? 1 : 0;
  // dut
  aes #(
    .SecMasking  ( `EN_MASKING   ),
    .SecSBoxImpl ( `SBOX_IMPL    )
  ) dut (
    .clk_i            ( clk                               ),
    .rst_ni           ( rst_n                             ),
    .rst_shadowed_ni  ( rst_shadowed_n                    ),

    .idle_o           ( idle_s                            ),
    .lc_escalate_en_i ( lc_escalate_en                    ),
    .clk_edn_i        ( edn_clk                           ),
    .rst_edn_ni       ( edn_rst_n                         ),
    .edn_o            ( edn_if[0].req                     ),
    .edn_i            ( {edn_if[0].ack, edn_if[0].d_data} ),
    .keymgr_key_i     ( sideload_if.sideload_key          ),

    .tl_i             ( tl_if.h2d                         ),
    .tl_o             ( tl_if.d2h                         ),

    .alert_rx_i       ( alert_rx                          ),
    .alert_tx_o       ( alert_tx                          )
  );

  initial begin
    // drive clk and rst_n from clk_if
    clk_rst_if.set_active();

    lc_escalate_if.drive('0);
    uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if);
    uvm_config_db#(virtual rst_shadowed_if)::set(null, "*.env", "rst_shadowed_vif",
                                                 rst_shadowed_if);
    uvm_config_db#(intr_vif)::set(null, "*.env", "intr_vif", intr_if);
    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);
    uvm_config_db#(virtual aes_cov_if)::set(null, "*.env", "aes_cov_if", dut.u_aes_cov_if );
    uvm_config_db#(virtual key_sideload_if)
                   ::set(null, "*.env.keymgr_sideload_agent*", "vif", sideload_if);

    uvm_config_db#(virtual pins_if #($bits(lc_ctrl_pkg::lc_tx_t) + 1))
                   ::set(null, "*.env", "lc_escalate_vif", lc_escalate_if);
    uvm_config_db#(virtual pins_if #(1))
                   ::set(null, "*.env", "idle_vif", idle_if);
    uvm_config_db#(virtual aes_reseed_if)::set(null, "*.env", "aes_reseed_vif",
                                               dut.u_aes_reseed_if);
    $timeformat(-12, 0, " ps", 12);
    run_test();
  end

  if (`EN_MASKING) begin : gen_aes_masking_reseed_vif
    initial begin
      uvm_config_db#(virtual aes_masking_reseed_if)::set(null, "*.env", "aes_masking_reseed_vif",
        dut.u_aes_core.u_aes_cipher_core.gen_masks.u_aes_prng_masking.u_aes_masking_reseed_if);
    end
  end
endmodule
