In reply to MahD:
Assuming the implementation of the built-in array locator methods have better performance, set_register task could be like
// ---------------------------------------------------------------------//
task automatic set_register(string block_name, string register_file,
string register_name, string field_name,
bit [3:0] RegisterValue);
uvm_reg_block reg_model;
uvm_reg_block reg_block;
uvm_reg regs[$];
uvm_reg_field fields[$];
uvm_status_e status;
uvm_reg register[$];
uvm_reg_field field[$];
string field_full_name;
string reg_full_name;
reg_model = m_env.m_ral.lckg_ral;
reg_block = reg_model.get_block_by_name(block_name);
if (reg_block == null)
`uvm_fatal_context("set_register", "lckg_ral block not found", uvm_root::get());
reg_block.get_registers(regs);
reg_block.get_fields(fields);
field_full_name = {reg_block.get_full_name(), ".", register_name, ".", field_name};
reg_full_name = {reg_block.get_full_name(), ".", register_name};
register = regs.find with(item.get_full_name() == reg_full_name);
field = fields.find with (item.get_full_name() == field_full_name);
// Check for the size of register and field
if(register.size != 1)
`uvm_fatal_context("REGISTER_NAME", "register name doesn't exist!!!", uvm_root::get());
if(field.size != 1)
`uvm_fatal_context("FIELD_NAME", "field name doesn't exist!!", uvm_root::get());
field[0].set(RegisterValue);
register[0].update(status);
endtask
For the nested foreachs, you could use the following equivalent one, I don’t think you will gain a performance, but it will be more readable.
foreach (cfg.paths[clk_i, clk_o, s1, s2, s3, s4]) begin
set_register("boston_lckg_lckg_csr", s2, s3, s4, cfg.paths[clk_i][clk_o][s1][s2][s3][s4]);
end
Note: I’ve partially compiled the code, to compile it fully I need the whole environment setup, but I guess you get the idea.