• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

UVM中get_name(), get_type_name(), get_type()的区别

UVM验证平台中提到函数,他们往往是定义在某个class中的,你调用某个函数其实是某个class中的函数!
我们今天说的get_name(), get_full_name(), get_type_name(), get_type(), set_name()这些小函数,用的时候,还真是各自class各自的定义!
在UVM中的class主要指的就是最常用的他们:uvm_component,uvm_sequence_item。

01 uvm_component中get_name系列小函数

比如在UVM验证平台中,我们在这样的一个class中调用这几个函数,代码如下:

class jerry_component extends uvm_component;
…
$display(“%0s”,get_name());
$display(“%0s”,get_full_name());
$display("%0s",get_type());
$display(“%0s”,get_type_name());
…
endclass

而这个class在env中例化:

class jerry_env extends uvm_env;
…
jerry_component u_jerry_c;
…
function void build_phase (uvm_phase phase);
  u_jerry_c = jerry_component::type_id::create(“u_jerry_so_cool”,this); //例化uvm_component
endfunction
…
endclass

jerry_env例化在base_test中名为u_jerry_env。
如上代码中jerry_component中调用的小函数打印出会是什么字符串呢?

1. get_name() 会打印出:

“u_jerry_so_cool”。
大家注意了!
相信很多人都会认为这个函数会打印出“u_jerry_c”,
实际竟然会是“u_jerry_so_cool”!
这个是哪里来的?
原来是这句u_jerry_c=jerry_component::type_id::create(“u_jerry_so_cool”,this);
例化的时候写进去的字符串啊!
使用u_jerry_c =new(“u_jerry_so_cool”)方式写进去的字符串也是一样的效果。为什么你会认为是打印这句“u_jerry_c”?
因为常常我们习惯于例化时候传入的字符串与这个名字是保持一致的!!

2. get_full_name()会打印出:

“uvm_test_top.u_jerry_env.u_jerry_so_cool”。
这带full的小函数,打印出的是路径名字。
这里要注意两点:
a.路径的结尾:“u_jerry_so_cool”。这个不要怀疑,就是get_name()拼出来的,而不是“u_jerry_c”。
b.路径的开头:“uvm_test_top”。记住打印的路径不是从UVM树根开始的!是树根的下一级。(Tip:树根路径对应“top”)

3. get_name()会打印出:

“jerry_component”。
对于uvm_component,这个get_type_name(),就是class的名字。

4. get_type_name()会打印出:

“jerry_component”。
对于uvm_component,这个get_type_name(),就是class的名字。

02、uvm_sequence_item中get_name系列小函数

class jerry_tr extends uvm_sequence_item;
…
`uvm_object_utils_begin( jerry_tr )
…
`uvm_object_utils_end
…
endclass
class jerry_component extends uvm_component;
jerry_tr u_tr;
…
u_tr=new(“jerry_is_good”);
…
$display(“%0s”,u_tr.get_name());
$display(“%0s”,u_tr.get_full_name());
$display(“%0s”,u_tr.get_type_name());
…
endclass

还是老规矩,先猜猜这几句打印什么?
然后再看下面的解释:

  1. u_tr.get_name() 会打印出:
    “jerry_is_good”。
    uvm_sequence_item中的get_name函数与uvm_component一样,是打印“new()”时候传入的字符串!
  2. u_tr.get_full_name()会打印出:
    “jerry_is_good”。//注意,这点和uvm_component不一样
    注意!!!
    对于uvm_sequence_item,get_full_name()与get_name()一样!
    因为它是不作为UVM树节点的,所以路径没有别的层次。
    这点保留了uvm_object原本的函数性质。
  3. u_tr.get_type_name()会打印出:
    “jerry_tr”。
    实际上,在原始的uvm_object的get_type_name()传出的是,也就是无返回值的。
    但是我们为什么看到此处打印的与uvm_component一样是一个class名呢?
    原因是因为这句话:
    uvm_object_utils_begin( jerry_tr ) … uvm_object_utils_end
    原来通过这几句话,UVM实际上会把uvm_object的get_type_name()函数重载,这个函数就会返回class名字!
    那我们屏蔽了它会出现什么呢?!
    如果你屏蔽了这几句,或者不需要这几句,u_tr.get_type_name()会打出“uvm_sequence_item”!!
    这个为什么?
    因为uvm_sequence_item里面本身也会重载这个函数!

03、关于set_name

在上述uvm_sequence_item中,我们加入set_name这样一行代码:

class jerry_component extends uvm_component;
jerry_tr u_tr;
…

u_tr=new(“jerry_is_good”);
u_tr.set_name(“jerry_is_cool”);
…
$display(“%0s”,u_tr.get_name());
$display(“%0s”,u_tr.get_full_name());
$display(“%0s”,u_tr.get_type_name());
…
endclass
  1. u_tr.get_name() 会打出“jerry_is_cool”。
  2. u_tr.get_full_name() 会打出“jerry_is_cool”。
  3. u_tr.get_type_name() 会打出“jerry_tr”。
    我们清楚的可以看出来,在uvm_sequence_item中,调用set_name是更改了“new()”中的字符串名,相当于这个字符串的名字重新改写了!
    同样,如果我们在uvm_component中使用set_name呢?
    我们在前文代码中加入:
class jerry_component extends uvm_component;
…
set_name(“I love jerry”);
…
endclass

各位注意了,这个时候不等打印,就会报出一个UVM_ERROR!!
大致如下:
It is illegal to change the name of a component. The component name will not be changed to “I love jerry”
原因:就是uvm_component使用set_name的时候希望其本身的名字是空的才能改名!
也就是说,uvm_component没名字才能起名字,名字一旦起好不能乱改!(因为好歹是一个UVM树的节点,还是要稳重点)。
其实,在uvm_component中new()的时候就会调用set_name()函数,所以uvm_component的这个函数一般不是给外人用的,我们就不改他的名字了。

posted on 2022-04-24 21:20  SOC验证工程师  阅读(1080)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3