// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

% if is_cip:
class ${name}_scoreboard extends cip_base_scoreboard #(
% else:
class ${name}_scoreboard extends dv_base_scoreboard #(
% endif
    .CFG_T(${name}_env_cfg),
    .RAL_T(${name}_reg_block),
    .COV_T(${name}_env_cov)
  );
  `uvm_component_utils(${name}_scoreboard)

  // local variables

  // TLM agent fifos
% for agent in env_agents:
  uvm_tlm_analysis_fifo #(${agent}_item) ${agent}_fifo;
% endfor

  // local queues to hold incoming packets pending comparison
% for agent in env_agents:
  ${agent}_item ${agent}_q[$];
% endfor

  `uvm_component_new

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
% for agent in env_agents:
    ${agent}_fifo = new("${agent}_fifo", this);
% endfor
  endfunction

  function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
  endfunction

  task run_phase(uvm_phase phase);
    super.run_phase(phase);
    fork
% for agent in env_agents:
      process_${agent}_fifo();
% endfor
    join_none
  endtask
% for agent in env_agents:

  virtual task process_${agent}_fifo();
    ${agent}_item item;
    forever begin
      ${agent}_fifo.get(item);
      `uvm_info(`gfn, $sformatf("received ${agent} item:\n%0s", item.sprint()), UVM_HIGH)
    end
  endtask
% endfor
% if is_cip:

  virtual task process_tl_access(tl_seq_item item, tl_channels_e channel = DataChannel);
    uvm_reg csr;
    bit     do_read_check   = 1'b1;
    bit     write           = item.is_write();
    uvm_reg_addr_t csr_addr = get_normalized_addr(item.a_addr);

    super.process_tl_access(item, channel);
    if (is_tl_err_exp || is_tl_unmapped_addr) return;

    // if access was to a valid csr, get the csr handle
    if (csr_addr inside {cfg.csr_addrs}) begin
      csr = ral.default_map.get_reg_by_offset(csr_addr);
      `DV_CHECK_NE_FATAL(csr, null)
    end
    end else begin
      `uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr))
    end

    if (channel == AddrChannel) begin
      // if incoming access is a write to a valid csr, then make updates right away
      if (write) csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask));
    end

    // process the csr req
    // for write, update local variable and fifo at address phase
    // for read, update predication at address phase and compare at data phase
    case (csr.get_name())
      // add individual case item for each csr
      default: begin
        `uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name()))
      end
    endcase

    // On reads, if do_read_check, is set, then check mirrored_value against item.d_data
    if (!write && channel == DataChannel) begin
      if (do_read_check) begin
        `DV_CHECK_EQ(csr.get_mirrored_value(), item.d_data,
                     $sformatf("reg name: %0s", csr.get_full_name()))
      end
      csr.predict(.value(item.d_data), .kind(UVM_PREDICT_READ));
    end
  endtask
% endif

  virtual function void reset(string kind = "HARD");
    super.reset(kind);
    // reset local fifos queues and variables
  endfunction

  function void check_phase(uvm_phase phase);
    super.check_phase(phase);
    // post test checks - ensure that all local fifos and queues are empty
  endfunction

endclass
