电子说
今天在添加环境的结束检查时候,突然发现ral_model的mirror()无论如何也不进行数据比对:
ral_model.xxx.predict(xxxx);
ral_model.mirror(status, UVM_CHECK);
我自己非常的确定语法肯定时没有问题的,但是无论往寄存器里predict什么奇怪的值进去,mirror时候都不会报错。这就非常令人费解了,于是只能去源码里找。
mirror的最底层逻辑在uvm_reg.svh:
if (check == UVM_CHECK)
exp = get_mirrored_value();
...
if (check == UVM_CHECK) void'(do_check(exp, v, map));
鉴于UVM_CHECK我已经传入了,get_mirrore_value()我也执行过确实predict进去了奇怪的值,那么问题只能出现在do_check这里(这个想了好久)。在do_check里我找到了一个核心的操作:
if (!(m_fields[i].get_compare() == UVM_NO_CHECK ||
acc == "WO")) begin
...
field本身不是UVM_NO_CHECK属性的话才会进行比对,那么问题是不是可能出现在field属性身上呢?转到uvm_reg_field.svh文件,找get_compare()方法:
function uvm_check_e uvm_reg_field::get_compare();
return m_check;
endfunction
进一步的看下m_check属性是怎么定义的:
function void uvm_reg_field::configure(uvm_reg parent,
int unsigned size,
int unsigned lsb_pos,
string access,
bit volatile,
uvm_reg_data_t reset,
bit has_reset,
bit is_rand,
bit individually_accessible);
...
m_check = volatile ? UVM_NO_CHECK : UVM_CHECK;
...
问题大概明确了,应该是field在进行configure是volatile赋值为1,查了一下确实如此:
this.xxxx.configure(this, 20, 0, "RW", 1, 20'h0000, 1, 1, 1);
那么问题就大概清晰了,溯源来看ral_model是通过ralf生成的,ralf是通过xml生成的,那么只能是xml中写错了:
< spirit:volatile >true< /spirit:volatile >
我这才理解了xml中这个“易失性”。之前就一直不明白,为啥一个仿真模型要关心volatile呢,原来如果易失性=true的话,环境认为你这个寄存器存不住值也就不会进行compare操作。于是将其修改为(或者直接删除,我就不应该多这一笔):
< spirit:volatile >false< /spirit:volatile >
重新生成ral_model后mirror(status, UVM_CHECK)生效报错。
全部0条评论
快来发表一下你的评论吧 !