blob: 28e1735656db7de766e05b474d278a4797eba43b [file]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class rv_dm_env_cfg extends cip_base_env_cfg #(.RAL_T(rv_dm_regs_reg_block));
// ext component cfgs
virtual rv_dm_if rv_dm_vif;
rand jtag_agent_cfg m_jtag_agent_cfg;
rand tl_agent_cfg m_tl_sba_agent_cfg;
// The JTAG DMI register model.
rand jtag_dmi_reg_block jtag_dmi_ral;
// The JTAG RV debugger model.
jtag_rv_debugger debugger;
// A constant that can be referenced from anywhere.
string mem_ral_name = "rv_dm_mem_reg_block";
`uvm_object_utils_begin(rv_dm_env_cfg)
`uvm_field_object(m_jtag_agent_cfg, UVM_DEFAULT)
`uvm_field_object(m_tl_sba_agent_cfg, UVM_DEFAULT)
`uvm_field_object(jtag_dmi_ral, UVM_DEFAULT)
`uvm_field_object(debugger, UVM_DEFAULT)
`uvm_object_utils_end
`uvm_object_new
virtual function void initialize(bit [31:0] csr_base_addr = '1);
list_of_alerts = rv_dm_env_pkg::LIST_OF_ALERTS;
tl_intg_alert_name = "fatal_fault";
// Set up second RAL model for debug memory and associated collateral
ral_model_names.push_back(mem_ral_name);
// both RAL models use same clock frequency
clk_freqs_mhz["rv_dm_mem_reg_block"] = clk_freq_mhz;
super.initialize(csr_base_addr);
`uvm_info(`gfn, $sformatf("ral_model_names: %0p", ral_model_names), UVM_LOW)
// Both, the regs and the debug mem TL device (in the DUT) only support 1 outstanding.
m_tl_agent_cfgs[RAL_T::type_name].max_outstanding_req = 1;
m_tl_agent_cfgs[mem_ral_name].max_outstanding_req = 1;
// Create jtag agent config obj
m_jtag_agent_cfg = jtag_agent_cfg::type_id::create("m_jtag_agent_cfg");
m_jtag_agent_cfg.if_mode = dv_utils_pkg::Host;
m_jtag_agent_cfg.is_active = 1'b1;
m_jtag_agent_cfg.ir_len = JTAG_IR_LEN;
// Set the 'correct' IDCODE register value to the JTAG DTM RAL.
m_jtag_agent_cfg.jtag_dtm_ral.idcode.set_reset(RV_DM_JTAG_IDCODE);
// Create TL agent config obj for the SBA port.
m_tl_sba_agent_cfg = tl_agent_cfg::type_id::create("m_tl_sba_agent_cfg");
m_tl_sba_agent_cfg.if_mode = dv_utils_pkg::Device;
m_tl_sba_agent_cfg.is_active = 1'b1;
jtag_dmi_ral = create_jtag_dmi_reg_block(m_jtag_agent_cfg);
// Fix the reset values of these fields based on our design.
`uvm_info(`gfn, "Fixing reset values in jtag_dmi_ral", UVM_LOW)
jtag_dmi_ral.hartinfo.dataaddr.set_reset(dm::DataAddr);
jtag_dmi_ral.hartinfo.datasize.set_reset(dm::DataCount);
jtag_dmi_ral.hartinfo.dataaccess.set_reset(1); // TODO: verify this!
jtag_dmi_ral.hartinfo.nscratch.set_reset(2); // TODO: verify this!
jtag_dmi_ral.abstractcs.datacount.set_reset(dm::DataCount);
jtag_dmi_ral.abstractcs.progbufsize.set_reset(dm::ProgBufSize);
jtag_dmi_ral.dmstatus.authenticated.set_reset(1); // No authentication performed.
jtag_dmi_ral.sbcs.sbaccess32.set_reset(1);
jtag_dmi_ral.sbcs.sbaccess16.set_reset(1);
jtag_dmi_ral.sbcs.sbaccess8.set_reset(1);
jtag_dmi_ral.sbcs.sbasize.set_reset(32);
apply_jtag_dmi_ral_csr_excl();
// Create the JTAG RV debugger instance.
debugger = jtag_rv_debugger::type_id::create("debugger");
debugger.set_cfg(m_jtag_agent_cfg);
debugger.set_ral(jtag_dmi_ral);
debugger.num_harts = NUM_HARTS;
endfunction
protected virtual function void post_build_ral_settings(dv_base_reg_block ral);
// The backdoor HDL paths are set incorrectly on the debug mem RAL structures by the reggen
// tool. We just remove all HDL paths and skip backdoor writes entirely.
// TODO: Enable backdoor writes later.
if (ral.get_name() == mem_ral_name) begin
uvm_reg regs[$];
ral.get_registers(regs);
foreach (regs[i]) begin
regs[i].clear_hdl_path("ALL");
end
end
endfunction
// Apply RAL exclusions externally since the RAL itself is considered generic. The IP it is used
// in constrains the RAL with its implementation details.
virtual function void apply_jtag_dmi_ral_csr_excl();
csr_excl_item csr_excl = jtag_dmi_ral.get_excl_item();
// We leave the DM 'activated' for CSR tests to reduce noise. We exclude this from further
// writes to avoid side-effects.
csr_excl.add_excl(jtag_dmi_ral.dmcontrol.dmactive.get_full_name(),
CsrExclWrite, CsrNonInitTests);
// This field is tied off to 0 due to no hart array mask being implemented.
// TODO: Change these to access policy.
csr_excl.add_excl(jtag_dmi_ral.dmcontrol.hasel.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.dmcontrol.hartreset.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
// Selecting a different hart in the middle of random read/writes impact other registers.
csr_excl.add_excl(jtag_dmi_ral.dmcontrol.hartsello.get_full_name(),
CsrExclWrite, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.dmcontrol.hartselhi.get_full_name(),
CsrExclWrite, CsrNonInitTests);
// Writes to other CSRs may affect dmstatus, even the HW reset test.
csr_excl.add_excl(jtag_dmi_ral.dmstatus.get_full_name(), CsrExclCheck, CsrAllTests);
// We have only upto dm::DataCount number of these registers available.
foreach (jtag_dmi_ral.abstractdata[i]) begin
if (i >= dm::DataCount) begin
csr_excl.add_excl(jtag_dmi_ral.abstractdata[i].get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
end
end
// We have only upto dm::ProgBufSize number of these registers available.
foreach (jtag_dmi_ral.progbuf[i]) begin
if (i >= dm::ProgBufSize) begin
csr_excl.add_excl(jtag_dmi_ral.progbuf[i].get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
end
end
// These prevent an SBA access from being triggered, which have other side effects.
csr_excl.add_excl(jtag_dmi_ral.sbcs.sbreadondata.get_full_name(),
CsrExclWrite, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.sbcs.sbreadonaddr.get_full_name(),
CsrExclWrite, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.sbdata0.get_full_name(),
CsrExclWrite, CsrNonInitTests);
// TODO: This should be an access policy change.
csr_excl.add_excl(jtag_dmi_ral.sbcs.sbaccess.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
// These SBA registers are not implemented, or unsupported due to 32-bit system.
csr_excl.add_excl(jtag_dmi_ral.sbaddress1.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.sbaddress2.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.sbaddress3.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.sbdata2.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
csr_excl.add_excl(jtag_dmi_ral.sbdata3.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
// Abstractcs cmderr bits are updated by RTL.
csr_excl.add_excl(jtag_dmi_ral.abstractcs.cmderr.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
// Not all bits of abstractauto are set - and its also impacted by writes to other CSRs.
csr_excl.add_excl(jtag_dmi_ral.abstractauto.get_full_name(),
CsrExclWriteCheck, CsrNonInitTests);
endfunction
endclass