blob: d565c9d48fd2f01935ad09ceabd3b7eb3b58a0dd [file] [log] [blame]
// 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),
% if has_ral:
.RAL_T(${name}_reg_block),
% endif
.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
% if has_alerts:
// TODO: remove once support alert checking
do_alert_check = 0;
% endif
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, string ral_name);
uvm_reg csr;
bit do_read_check = 1'b1;
bit write = item.is_write();
uvm_reg_addr_t csr_addr = cfg.ral_models[ral_name].get_word_aligned_addr(item.a_addr);
bit addr_phase_read = (!write && channel == AddrChannel);
bit addr_phase_write = (write && channel == AddrChannel);
bit data_phase_read = (!write && channel == DataChannel);
bit data_phase_write = (write && channel == DataChannel);
// if access was to a valid csr, get the csr handle
if (csr_addr inside {cfg.ral_models[ral_name].csr_addrs}) begin
csr = cfg.ral_models[ral_name].default_map.get_reg_by_offset(csr_addr);
`DV_CHECK_NE_FATAL(csr, null)
end
else begin
`uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr))
end
// if incoming access is a write to a valid csr, then make updates right away
if (addr_phase_write) begin
void'(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
"intr_state": begin
// FIXME
do_read_check = 1'b0;
end
"intr_enable": begin
// FIXME
end
"intr_test": begin
// FIXME
end
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 (data_phase_read) 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
void'(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