// 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 otp_ctrl_env_pkg::*;
  import otp_ctrl_test_pkg::*;
  import otp_ctrl_reg_pkg::*;
  import mem_bkdr_util_pkg::mem_bkdr_util;

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

  // TB base test ENV_T & CFG_T specification
  //
  // Specify the parameters for the otp_ctrl_base_test
  // This will invoke the UVM registry and link this test type to
  // the name 'otp_ctrl_base_test' as a test name passed by UVM_TESTNAME
  //
  // This is done explicitly only for the prim_pkg::ImplGeneric implementation
  // since partner base tests inherit from otp_ctrl_base_test#(CFG_T, ENV_T) and
  // specify directly (CFG_T, ENV_T) via the class extension and use a different
  // UVM_TESTNAME
  if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin : gen_spec_base_test_params
    typedef otp_ctrl_base_test #(.CFG_T(otp_ctrl_env_cfg),
                                 .ENV_T(otp_ctrl_env)) otp_ctrl_base_test_t;
  end

  wire clk, rst_n;
  wire devmode;
  wire otp_ctrl_pkg::flash_otp_key_req_t flash_req;
  wire otp_ctrl_pkg::flash_otp_key_rsp_t flash_rsp;
  wire otp_ctrl_pkg::otbn_otp_key_req_t  otbn_req;
  wire otp_ctrl_pkg::otbn_otp_key_rsp_t  otbn_rsp;
  wire otp_ctrl_pkg::sram_otp_key_req_t[NumSramKeyReqSlots-1:0] sram_req;
  wire otp_ctrl_pkg::sram_otp_key_rsp_t[NumSramKeyReqSlots-1:0] sram_rsp;

  wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
  wire intr_otp_operation_done, intr_otp_error;

  wire otp_ctrl_pkg::otp_ast_req_t ast_req;
  tlul_pkg::tl_d2h_t prim_tl_o;

  // interfaces
  clk_rst_if clk_rst_if(.clk(clk), .rst_n(rst_n));
  pins_if #(NUM_MAX_INTERRUPTS) intr_if(interrupts);
  pins_if #(1) devmode_if(devmode);

  // lc_otp interfaces
  push_pull_if #(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1))
               lc_prog_if(.clk(clk), .rst_n(rst_n));
  push_pull_if #(.DeviceDataWidth(SRAM_DATA_SIZE))
               sram_if[NumSramKeyReqSlots](.clk(clk), .rst_n(rst_n));
  push_pull_if #(.DeviceDataWidth(OTBN_DATA_SIZE)) otbn_if(.clk(clk), .rst_n(rst_n));
  push_pull_if #(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_addr_if(.clk(clk), .rst_n(rst_n));
  push_pull_if #(.DeviceDataWidth(FLASH_DATA_SIZE)) flash_data_if(.clk(clk), .rst_n(rst_n));

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

  otp_ctrl_if otp_ctrl_if(.clk_i(clk), .rst_ni(rst_n));

  `DV_ALERT_IF_CONNECT

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

  assign otp_ctrl_if.lc_prog_req = lc_prog_if.req;
  assign otp_ctrl_if.lc_prog_err = lc_prog_if.d_data;

  // Assign to otp_ctrl_if for assertion checks.
  assign otp_ctrl_if.lc_prog_ack = lc_prog_if.ack;
  assign otp_ctrl_if.flash_acks = flash_data_if.ack;
  assign otp_ctrl_if.otbn_ack  = otbn_if.ack;

  // This signal probes design's alert request to avoid additional logic for triggering alert and
  // disable assertions.
  // Alert checkings are done independently in otp_ctrl's scb.
  // The correctness of this probed signal is checked in otp_ctrl's scb as well.
  assign otp_ctrl_if.alert_reqs = dut.alerts[0] | dut.alerts[1];

  // connected to interface
  wire otp_ext_voltage_h = otp_ctrl_if.ext_voltage_h_io;

  // dut
  otp_ctrl dut (
    .clk_i                      (clk        ),
    .rst_ni                     (rst_n      ),
    // edn
    .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}),
    // bus interfaces
    .core_tl_i                  (tl_if.h2d  ),
    .core_tl_o                  (tl_if.d2h  ),
    .prim_tl_i                  (prim_tl_if.h2d),
    .prim_tl_o                  (prim_tl_if.d2h),
    // interrupt
    .intr_otp_operation_done_o  (intr_otp_operation_done),
    .intr_otp_error_o           (intr_otp_error),
    // alert
    .alert_rx_i                 (alert_rx   ),
    .alert_tx_o                 (alert_tx   ),
    // ast
    .otp_ast_pwr_seq_o          (ast_req),
    .otp_ast_pwr_seq_h_i        (otp_ctrl_if.otp_ast_pwr_seq_h_i),
    // pwrmgr
    .pwr_otp_i                  (otp_ctrl_if.pwr_otp_init_i),
    .pwr_otp_o                  ({otp_ctrl_if.pwr_otp_done_o, otp_ctrl_if.pwr_otp_idle_o}),
    // lc
    .lc_otp_vendor_test_o       (otp_ctrl_if.otp_vendor_test_status_o),
    .lc_otp_vendor_test_i       (otp_ctrl_if.otp_vendor_test_ctrl_i),
    .lc_otp_program_i           ({lc_prog_if.req, lc_prog_if.h_data}),
    .lc_otp_program_o           ({lc_prog_if.d_data, lc_prog_if.ack}),
    .lc_creator_seed_sw_rw_en_i (otp_ctrl_if.lc_creator_seed_sw_rw_en_i),
    .lc_seed_hw_rd_en_i         (otp_ctrl_if.lc_seed_hw_rd_en_i),
    .lc_dft_en_i                (otp_ctrl_if.lc_dft_en_i),
    .lc_escalate_en_i           (otp_ctrl_if.lc_escalate_en_i),
    .lc_check_byp_en_i          (otp_ctrl_if.lc_check_byp_en_i),
    .otp_lc_data_o              (otp_ctrl_if.lc_data_o),
    // keymgr
    .otp_keymgr_key_o           (otp_ctrl_if.keymgr_key_o),
    // flash
    .flash_otp_key_i            (flash_req),
    .flash_otp_key_o            (flash_rsp),
    // sram
    .sram_otp_key_i             (sram_req),
    .sram_otp_key_o             (sram_rsp),
    // otbn
    .otbn_otp_key_i             (otbn_req),
    .otbn_otp_key_o             (otbn_rsp),

    .otp_hw_cfg_o               (otp_ctrl_if.otp_hw_cfg_o),
    .otp_ext_voltage_h_io       (otp_ext_voltage_h),

    //scan
    .scan_en_i                  (otp_ctrl_if.scan_en_i),
    .scan_rst_ni                (otp_ctrl_if.scan_rst_ni),
    .scanmode_i                 (otp_ctrl_if.scanmode_i),

    // Test-related GPIO output
    .cio_test_o                 (otp_ctrl_if.cio_test_o),
    .cio_test_en_o              (otp_ctrl_if.cio_test_en_o)
  );

  for (genvar i = 0; i < NumSramKeyReqSlots; i++) begin : gen_sram_pull_if
    assign sram_req[i]              = sram_if[i].req;
    assign sram_if[i].ack           = sram_rsp[i].ack;
    assign sram_if[i].d_data        = {sram_rsp[i].key, sram_rsp[i].nonce, sram_rsp[i].seed_valid};
    assign otp_ctrl_if.sram_acks[i] = sram_rsp[i].ack;
    initial begin
      uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(SRAM_DATA_SIZE)))::set(null,
                     $sformatf("*env.m_sram_pull_agent[%0d]*", i), "vif", sram_if[i]);
    end
  end
  assign otbn_req       = otbn_if.req;
  assign otbn_if.ack    = otbn_rsp.ack;
  assign otbn_if.d_data = {otbn_rsp.key, otbn_rsp.nonce, otbn_rsp.seed_valid};

  assign flash_req            = {flash_data_if.req, flash_addr_if.req};
  assign flash_data_if.ack    = flash_rsp.data_ack;
  assign flash_addr_if.ack    = flash_rsp.addr_ack;
  assign flash_data_if.d_data = {flash_rsp.key, flash_rsp.seed_valid};
  assign flash_addr_if.d_data = {flash_rsp.key, flash_rsp.seed_valid};

  assign interrupts[OtpOperationDone] = intr_otp_operation_done;
  assign interrupts[OtpErr]           = intr_otp_error;

  // Instantitate the memory backdoor util instance only for OS implementation
  // Proprietary IP will instantiate their own backdoor util

  if (`PRIM_DEFAULT_IMPL == prim_pkg::ImplGeneric) begin : gen_impl_generic
    `define MEM_MODULE_PATH \
        tb.dut.u_otp.gen_generic.u_impl_generic.u_prim_ram_1p_adv

    `define MEM_ARRAY_PATH \
        `MEM_MODULE_PATH.u_mem.gen_generic.u_impl_generic.mem

    initial begin : mem_bkdr_util_gen
      mem_bkdr_util m_mem_bkdr_util;
      m_mem_bkdr_util = new(.name("mem_bkdr_util"),
                            .path(`DV_STRINGIFY(`MEM_ARRAY_PATH)),
                            .depth($size(`MEM_ARRAY_PATH)),
                            .n_bits($bits(`MEM_ARRAY_PATH)),
                            .err_detection_scheme(mem_bkdr_util_pkg::EccHamming_22_16));

      uvm_config_db#(mem_bkdr_util)::set(null, "*.env", "mem_bkdr_util", m_mem_bkdr_util);
    end : mem_bkdr_util_gen

    `undef MEM_ARRAY_PATH
    `undef MEM_MODULE_PATH
  end : gen_impl_generic

  initial begin
    // These SVA checks the lc_escalate_en is either Off or On, we will use more than these
    // 2 values.
    // If the value is not lc_ctrl_pkg::Off, design will treat it as lc_ctrl_pkg::On.
    $assertoff(0, tb.dut.u_prim_lc_sync_escalate_en.PrimLcSyncCheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_escalate_en.PrimLcSyncCheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_escalate_en.PrimLcSyncCheckTransients1_A);

    // These SVA checks the lc_sync_seed_hw_rd_en is either Off or On, we will use more than these
    // 2 values.
    // If the value is not lc_ctrl_pkg::On, design will treat it as lc_ctrl_pkg::Off.
    $assertoff(0, tb.dut.u_prim_lc_sync_seed_hw_rd_en.PrimLcSyncCheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_seed_hw_rd_en.PrimLcSyncCheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_seed_hw_rd_en.PrimLcSyncCheckTransients1_A);

    // These SVA checks the lc_check_byp_en is either Off or On, we will use more than these
    // 2 values.
    // If the value is not lc_ctrl_pkg::On, design will treat it as lc_ctrl_pkg::Off.
    $assertoff(0, tb.dut.u_prim_lc_sync_check_byp_en.PrimLcSyncCheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_check_byp_en.PrimLcSyncCheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_check_byp_en.PrimLcSyncCheckTransients1_A);

    // These SVA checks the lc_dft_en is either Off or On, we will use more than these 2 values.
    // If the value is not lc_ctrl_pkg::On, design will treat it as lc_ctrl_pkg::Off.
    $assertoff(0, tb.dut.u_prim_lc_sync_dft_en.PrimLcSyncCheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_dft_en.PrimLcSyncCheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_dft_en.PrimLcSyncCheckTransients1_A);
    $assertoff(0, tb.dut.u_tlul_lc_gate.u_err_en_sync.PrimLcSyncCheckTransients_A);
    $assertoff(0, tb.dut.u_tlul_lc_gate.u_err_en_sync.PrimLcSyncCheckTransients0_A);
    $assertoff(0, tb.dut.u_tlul_lc_gate.u_err_en_sync.PrimLcSyncCheckTransients1_A);

    // These SVA checks the lc_sync_creator_seed_sw_rw_en is either Off or On, we will use more
    // than these 2 values.
    // If the value is not lc_ctrl_pkg::On, design will treat it as lc_ctrl_pkg::Off.
    $assertoff(0, tb.dut.u_prim_lc_sync_creator_seed_sw_rw_en.PrimLcSyncCheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_creator_seed_sw_rw_en.PrimLcSyncCheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_creator_seed_sw_rw_en.PrimLcSyncCheckTransients1_A);

    // DV forced otp_cmd_i to reach invalid state, thus violate the assertions
    $assertoff(0, tb.dut.gen_partitions[3].gen_buffered.u_part_buf.OtpErrorState_A);
    $assertoff(0, tb.dut.gen_partitions[4].gen_buffered.u_part_buf.OtpErrorState_A);
    $assertoff(0, tb.dut.gen_partitions[5].gen_buffered.u_part_buf.OtpErrorState_A);
    $assertoff(0, tb.dut.gen_partitions[6].gen_buffered.u_part_buf.OtpErrorState_A);

    // 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);
    uvm_config_db#(virtual clk_rst_if)::set(null, "*.env",
                                            "clk_rst_vif_otp_ctrl_prim_reg_block", clk_rst_if);
    uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent_otp_ctrl_core_reg_block*",
                                       "vif", tl_if);
    uvm_config_db#(virtual tl_if)::set(null, "*.env.m_tl_agent_otp_ctrl_prim_reg_block",
                                       "vif", prim_tl_if);
    uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(OTBN_DATA_SIZE)))::set(null,
                   "*env.m_otbn_pull_agent*", "vif", otbn_if);
    uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(FLASH_DATA_SIZE)))::set(null,
                   "*env.m_flash_data_pull_agent*", "vif", flash_data_if);
    uvm_config_db#(virtual push_pull_if#(.DeviceDataWidth(FLASH_DATA_SIZE)))::set(null,
                   "*env.m_flash_addr_pull_agent*", "vif", flash_addr_if);
    uvm_config_db#(virtual push_pull_if#(.HostDataWidth(LC_PROG_DATA_SIZE), .DeviceDataWidth(1)))::
                   set(null, "*env.m_lc_prog_pull_agent*", "vif", lc_prog_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 otp_ctrl_if)::set(null, "*.env", "otp_ctrl_vif", otp_ctrl_if);
    $timeformat(-12, 0, " ps", 12);
    run_test();
  end

endmodule
