I've a simple sequence
regmodel.REGx.write (...)
Lets consider I've 8 registers under regmodel viz. REG0, REG1, REG2,....,REG7 I would like to pass number as a test plus argument, say +NUM=4
Using $sformat or $psprintf, I can create string variable with proper register name for e.g.
if ($value$plusargs ("NUM=%0d", num))
$display ("Testcase passed %0d num", num);
else
num = 0;
$sformat (regName, "REG%0d", num);
now I've regName but I can't use following:
regmodel.regName.write (...)
regName is of type string and regmodel doens't have any register names regName, Is there any other way to achieve this? I was looking at get_name, get_full_name but those couldn't help in this case.
For now I can have if - else 8 times or a case statement, however it would be really inconvenient for large number of registers.
You can certainly find a register using a string which has been composed programmatically. You will need to use uvm_reg_block::get_reg_by_name
.
The usage will look something like this:
function void write_reg_by_num(int num, bit[31:0] data);
string reg_name = $sformatf("REG%0d", num);
uvm_reg reg = regmodel.get_reg_by_name(reg_name);
if (reg == null) begin
// No reg was found... you likely want to flag an error here
end else begin
uvm_status_e status;
reg.write(status, data);
end
endfunction
Note that the resulting uvm_reg
object is of the base class type, so if you want to access individual fields you need to use the base class methods to access the fields. That is, you need to use the methods on uvm_reg
, e.g. uvm_reg::get_field_by_name