// 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;

  // 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));

  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;
  // 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];

  // leave this unconnected for now.
  wire otp_ext_voltage_h;

  // 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.req ),
    .edn_i                      ({edn_if.ack, edn_if.d_data}),
    // bus interfaces
    .core_tl_i                  (tl_if.h2d  ),
    .core_tl_o                  (tl_if.d2h  ),
    // TODO: add second TL interface
    .prim_tl_i                  ('0         ),
    .prim_tl_o                  ('0         ),
    // 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        (ast_req),
    .otp_alert_o                (otp_ctrl_if.otp_alert_o),
    // 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_program_i           ({lc_prog_if.req, lc_prog_if.h_data, otp_ctrl_if.otp_test_ctrl_i}),
    .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                 (lc_ctrl_pkg::Off),

    // Test-related GPIO output
    .cio_test_o                 (),
    .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};
    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 it's not Off, it should be On.
    $assertoff(0, tb.dut.u_prim_lc_sync_escalate_en.CheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_escalate_en.CheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_escalate_en.CheckTransients1_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 it's not On, it should be Off.
    $assertoff(0, tb.dut.u_prim_lc_sync_seed_hw_rd_en.CheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_seed_hw_rd_en.CheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_seed_hw_rd_en.CheckTransients1_A);

    // These SVA checks the lc_check_byp_en is either Off or On, we will use more than these
    // 2 values.
    // If it's not On, it should be Off.
    $assertoff(0, tb.dut.u_prim_lc_sync_check_byp_en.CheckTransients_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_check_byp_en.CheckTransients0_A);
    $assertoff(0, tb.dut.u_prim_lc_sync_check_byp_en.CheckTransients1_A);

    // DV forced otp_cmd_i to reach invalid state, thus violate the assertions
    $assertoff(0, tb.dut.gen_partitions[2].gen_buffered.u_part_buf.OtpErrorState_A);
    $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);

    // 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 tl_if)::set(null, "*.env.m_tl_agent_otp_ctrl_core_reg_block*",
                                       "vif", 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
