我有一个简单的序列
regmodel.REGx.write (...)
让我们考虑在regmodel下我有8个寄存器。 REG0,REG1,REG2,....,REG7 我想将数字作为测试加参数传递,比如说+ NUM = 4
使用$ sformat或$ psprintf,我可以使用正确的寄存器名称创建字符串变量 例如。
if ($value$plusargs ("NUM=%0d", num))
$display ("Testcase passed %0d num", num);
else
num = 0;
$sformat (regName, "REG%0d", num);
现在我已经注册了但是我不能使用以下内容:
regmodel.regName.write (...)
regName是string类型,regmodel没有任何寄存器名称regName,还有其他方法可以实现吗?我在看get_name,get_full_name,但在这种情况下,这些都无济于事。
现在我可以使用if - else 8次或case case,但是对于大量的寄存器来说真的很不方便。
答案 0 :(得分:4)
你当然可以使用以编程方式编写的字符串找到一个寄存器。您需要使用uvm_reg_block::get_reg_by_name
。
用法看起来像这样:
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
请注意,生成的uvm_reg
对象属于基类类型,因此如果要访问单个字段,则需要使用基类方法来访问字段。也就是说,您需要使用uvm_reg
上的方法,例如uvm_reg::get_field_by_name