前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >啥?100个agent?这个台子怎么搭?(下)

啥?100个agent?这个台子怎么搭?(下)

作者头像
IC验证
发布2020-06-30 11:29:21
6110
发布2020-06-30 11:29:21
举报
文章被收录于专栏:杰瑞IC验证

来源| 杰瑞IC验证(ID:Jerry_IC) |原创作者| Jerry

书接上回,闲话不表。

上回说到,我们接到了一个需要100个相同agent的验证平台的活,我们已经写好了agent、宏定义、顶层的连接。

但是还有很多问题需要处理,比如:

100个agent,env中怎么声明例化?

seq怎么设计?

功能覆盖率怎么收集?

进行验证的时候用怎样的策略等等,今天我们就一起解决了它!

1.在env中例化我们的agent

100个agent,我们怎么在env中例化呢?

没错,在上篇中顶层例化不能用的那个方法这里可以用了!

---我们把agent声明和例化成size为100的数组嘛~

有人问了,agent可以声明成数组?这个不是一个class吗?它又不是像bit、int这种数据类型?

这种声明还可以理解,比如:int aa[100]; 你这个class难道可以这么声明成数组?jerry_agent aa[100]; 这么写对吗?

哈哈,不要怀疑,class就是最强大的数据类型!

结构体都可以这么声明,class为啥不行?

刚才你写的这两句里,jerry_agent aa[100]里的jerry_agent的角色就可以看作int aa[100]里面的int,此时他们的职能可以理解为是一样的。

同理,我们在env中声明和例化也可如此,直接上代码!

代码语言:javascript
复制
class jerry_env extends uvm_env;
……
jerry_agent   u_jerry_agt[`AGENT_NUM];
function void build_phase(uvm_phase phase);
      ……
     for(int i=0;i<`AGENT_NUM;i++) begin
u_jerry_agt[i]=jerry_agent::type_id::create($sformatf(“u_jerry_agt[%0d]”,i),this);
end
……
endfunction
endclass

如上,我们又用起了我们心爱的小宏宏`AGENT_NUM,把jerry_agent声明成了size为`AGENT_NUM的数组,并在build_phase中借用for循环例化了起来。

顺便提一下,比如我们想在env中把刚才例化的agent和别的组件连接起来,也可以同样的直接当数组,用循环来搞定!

可以在connect_phase中,把它和APPLE这个组件的port相连:

代码语言:javascript
复制
function void connect_phase(uvm_phase phase);

for(int i=0;i<`AGENT_NUM;i++) begin

u_jerry_agt[i].ap.connect(APPLE.port);

end

endfunction

2.Sequence的组织

100个人心中有100个哈姆雷特,100个agent就有100个sequence。怎么组织和启动这些sequence呢?

这么多同类型的sequence,其实还是使用虚拟sequence机制进行组织比较友好。

有了Jerry前面的思路,这里怎么写其实也不是那么难了,例如在虚拟sequencer中,我们声明100个实体sequencer,还是声明成数组:

代码语言:javascript
复制
class jerry_vser extends uvm_sequencer;

……

jerry_sequencer  sqr[`AGENT_NUM];

……

endclass

在虚拟sequence中,怎么启动这100个sequence呢?

既然定义成数组了,那当然还是用循环再加seq的启动代码来启动了。

对,现在大家已经很上道了!

这里需要注意的一点是,通常这100个seq肯定不是串行顺序的执行,而是并行启动和执行,这个并行执行就有坑了!

我们提到用循环和并行启动执行,当然很容易想到了for + fork-join_none结构。

这个在Jerry之前的一篇文章刚好提过,想不到那篇文章提到的坑,我们现在实实在在的就碰到了啊!这段在虚拟sequence中的核心代码,我们应该这么写:

代码语言:javascript
复制
 `uvm_declare_p_sequencer(jerry_vser)

……

for(int i=0; i<`AGENT_NUM ;i++) fork

automatic int j=i;

`uvm_do_on_with(seq.p_sequencer.sqr[j],{……})

join_none

说到这个实际场景,多说一句,这种启动seq的结构,你需要结合实际应用和seq的具体行为决定是否需要在join_none后面多加一句“wait fork;”,以防止虚拟seq的结束把启动起来的seq kill掉了。

这个不是我们今天的重点,不在此展开了,大家在实际玩的过程中慢慢体会啦~

3.功能覆盖率的收集

功能覆盖率收集接口信号或者变量的值,我们得到的是值但是关心的是值的信息。功能覆盖率代码编写要点3个字概括:“定、例、采”。

即定义covergroup,例化covergroup,以及在需要收集的时间点进行采集。

对于没有玩过覆盖率的初学者这里也可以先只是简单了解下,关注后续Jerry的文章会给大家从根上细聊的哈,这里不多说了。

我们要收集这100个agent的接口信息,这个covergroup也总不能写100次吧?怎么收集?

这里Jerry给大家提供的一种方法,还是顺着刚才的思路,大家可以先想想。

没错!正如各位天才想的那样,用class把covergroup包裹起来,然后把这个class例化成size为100的数组,套路和前面一样。

比如我们把covergroup包成这样一个class:

代码语言:javascript
复制
class panda;

covergroup AAA with function sample(int signal);

option.per_instance=1;

detect:coverpoint detect_signal {

     bins one  ={1};

     bins zero ={0};

}   

endgroup

endclass

然后我们把这个叫panda的class,在一个合适的地方例化100个,再让其与100个agent各自的接口产生联系进行收集就可以了,这个合适的地方你可以自己依照自己的平台结构决定,当然也可以像Jerry示例讲解的这样,使用一个专门的component去收集覆盖率,我们挑几个关键步骤聊聊:

首先,在这个class里,先把刚才的covergroup声名出来、以及把我们的100个接口声名出来,如下:

代码语言:javascript
复制
panda    u_panda_cov[`AGENT_NUM];

virtual jerry_interface   jerry_vif[`AGENT_NUM];

然后,我们把covergroup例化了,把virtual jerry_interface通过config_db机制拿到(对应回顾上篇在顶层把这100个接口通过config_db传出去了)。

代码语言:javascript
复制
for(int i=0;i<`AGENT_NUM;i++) begin

if(!uvm_config_db#(virtual jerry_interface)::get(null,$sformatf(“*u_jerry_agt[%0d]*”,i), “jerry_vif”, jerry_vif[i])

          `uvm_fatal(……)

end

     

for(int i=0;i<`AGENT_NUM;i++) begin

     u_panda_cov[i]=new();

end

最后,把接口和covergroup连起来进行采集,如下,在flag上升沿采集一下即可:

代码语言:javascript
复制
@(posedge xxx.flag)//这句只是示例,大家可以各种姿势采集

for(int i=0; i<`AGENT_NUM;i++) fork

automatic int j=i;

u_panda_cov[j].AAA.sample(jerry_vif[j].aa);  

join_none

好了,我们接的这趟活,到现在为止在代码层面上需要考虑的特殊点应该已经搞定了!

但是,在开展验证的时候100个agent跑的会不会很慢呢?

哈哈,当然会很慢!

不过说实话,现实中也不可能有需要100个agent这么多的RTL。

不过不管多少个,对于这样很多相同类型的、agent之间独立的接口,我们的验证case制造策略,还是要本着简单原则,比如大部分的case我们只随机使能其中两个agent,别的都不使能甚至可以改写成根本不例化,等大部分的功能验证完成之后,再制造几个特殊的所有agent都用上的、火力全开的定向case进行覆盖即可。

说到底还是验证重点、优先级的把握问题,如果每个case都是所有的agent全开进行验证,那样验证效率低下不说,更重要的可能导致心态爆裂而死~

哈哈,Jerry今天的文章又即将进入尾声了,也许有一些内容在很多初学者看来信息量有点大或者有一些迷茫,没关系,不要着急慢慢来,可以先收藏起来,以后总会有用的哈。

坚持看杰瑞IC验证公众号,进步从一点一滴开始,从当下开始,加油!!

祝各位越来越牛逼!我们下次再聊~

——The End——

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杰瑞IC验证 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.在env中例化我们的agent
  • 2.Sequence的组织
  • 3.功能覆盖率的收集
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档