UVM(九)之sequence机制续2

UVM(九)之sequence机制续2

1. 用事件做sequence之间的同步

到目前为止,sequence机制就是一个sequence启动之后对应一个sequencer,这个sequence发出transaction,sequencer把这个transaction转交给driver。

但是考虑这样一种情况,验证平台中有两个driver,这个连哥哥driver分别做不同的事情,第一个driver相当于一个CPU,它要在DUT刚启动的时候,配置DUT的寄存器,当它配置完成后,另外一个driver才能发激励。这种情况下在现实中是很常见的。一块DUT在上电复位后虽然其默认的参数就可以工作,但是大部分情况下,CPU还要对DUT做一些配置,这样才能DUT工作在我们期望的方式下。这个问题中,主要的就是一个同步的过程,一种很自然的想法就是把这个同步的过程使用一个event来完成:

之后,通过uvm_config_db的方式分别把两个sequence作为cpu_sequence和mac_sequence的default_sequence:

uvm_config_db#(uvm_objection_wrapper)::set(this,”env_sqr.main_phase”,”default_sequence”,cpu_seq::type_id::get());

uvm_config_db#(uvm_objection_wrapper)::set(this,”env_sqr.main_phase”,”default_sequence”,mac_seq::type_id::get());

当进入到main_phase时,这两个sequence会同步的启动,但是由于mac_seq要config_over事件的到来,所以它并不会马上产生transaction。而cpu_seq则会直接产生transaction,交给cpu_driver。当所有的配置工作完成后,config_over事件被触发,于是mac_seq开始产生transaction。

2. 复杂的同步:virtual sequence

上面的解决同步方法看起来非常的简单实用,不过这里有两个问题,第一个问题就是使用了一个全局的事件config_over。全局变量对于初写代码的人来说是非常受欢迎的,但是应该尽量避免使用全局变量的使用。

第二个问题是上面只是实现了一次同步,如果是有多次同步怎么办?如sequence A要先执行,之后是B,B完了才能是C,C完了才是D,这样显得很笨拙。

实现sequence之间同步的最好的方式就是使用virtual sequence。从字面上理解,虚拟的sequence。虚拟的意思就是它根本不发送transaction,它只是控制其他的sequence,起统一调度的作用。

如图所示,为了使用virtual sequence,一般的需要一个virtual sequencer。virtual sequencer里面包含指向其他实际sequencer的指针。

在test中,可以例化vsqr,并把相应的sequencer赋值给vsqr中的sequencer的指针。

3. 在sequence中慎用fork....join_none

假设DUT中有四个完全相同的MAC,那么相应的验证平台也要有4个完全相同的driver,sequencer。那么vsequencer就要这样定义:

当DUT上电复位,CPU把寄存器配置完成后,需要四个mac_driver同时发送数据,在vseq中可以使用fork来使四个driver同时发送数据:

这里使用了join_none,由于join_none的特性,系统并不等fork起来的进程结束就进入了下一次的fork循环,因此上面的for循环展开后如下:

现在我们要写一个新的sequence,他可以替代上面的两种包,可以这样写:

当sequence启动起来的时候,会自动执行这个sequence的body任务。当body任务完成的时候,那么这个sequence就相当于完成了其使命,已经结束了。如果使用fork...join_none,当使用uvm_do_on宏把四个mseq分别放在四个mac_sqr上执行时,系统会新启动4个进程,但是系统并不等待这4个mseq执行完毕就直接返回了。返回之后就到了endtask,此时系统认为这个sequence已经执行完成了。执行完成之后,系统会清理这个sequence之前占据的内存空间,杀死由其启动起来的进程,由于这4个启动起来的mseq还没有完成就直接被系统杀死掉了,也就是说,看似分别往4个mac_sqr分别丢了一个sequence,但是事实上这个sequence根本没有执行,这就是关键所在!

要避免这个问题可以使用wait fork或者fork....join

4. 在virtual sequence中控制验证平台的关闭

在sequence中使用starting_phase来控制验证平台的关闭。只有把此sequence作为sequencer的某动态运行phase的default_sequence时,其starting_phase才不为NULL。所以如果把某sequence作为uvm_do宏的参数,那么此sequence中的starting_phase是为null的。在此sequence中使用starting_phase.raise_objection是会产生问题。这个问题是比较容易解决的,只要把父sequence的starting_phase赋值给子sequence的starting_phase就可以了,这样只要最顶层的sequence的starting_phase不为null,那么下面所有由其启动的sequence的starting_phase也不为null。

原文发布于微信公众号 - 瓜大三哥(xiguazai_tortoise)

原文发表时间:2017-10-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Web项目聚集地

Javascript中的异步

742
来自专栏架构师之旅

Oracle的常见问题汇总(3) ——​数据库死锁原因及解决办法

数据库死锁原因及解决办法 所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时...

1815
来自专栏ml

c/c++----网站及其后门(CGI应用程序)

      C/C++学习到这儿,结合自己曾经学过的javasweb知识,现在让我们来看看,如何做一个CGI程序吧!       首先了解一下啥子叫CGI  :...

3434
来自专栏Java技术栈

75 道 BAJT 中高级 Java 面试题,你能答上几道?

整理了下 BATJ 关于 JAVA 的面试题目,大家参考下吧,希望对大家有所帮助,可以帮大家查漏不缺。

992
来自专栏智能大石头

NewLife.Net——构建可靠的网络服务

1523
来自专栏有趣的Python

12- vue django restful framework 打造生鲜超市 -商品详情页,商品收藏

只需要在继承的里面添加这个mixins.RetrieveModelMixin就可以了。

1814
来自专栏智能大石头

NewLife.Net——构建可靠的网络服务

老规矩,先上源码:https://github.com/nnhy/NewLife.Net.Tests

1140
来自专栏开源项目

码云推荐 | 基于 ActiveRecord 模式的 ORM 框架 Hare

hare是一个基于pymysql并运用 ActiveRecord 模式的 ORM 框架。 项目简介 hare是一个基于pymysql并运用ActiveRecor...

3246
来自专栏企鹅号快讯

JDBC编程

前面我们已经讨论了数据库的安装和简单的使用,还没完成的可以先去Mysql的安装和Mysql数据库的简单操作回顾一下哦!今天我们来简单学习JDBC编程的准备和链...

3358
来自专栏IT技术精选文摘

分布式事务原理与实践

事务简介 事务的核心是锁和并发,采用同步控制的方式保证并发的情况下性能尽可能高,且容易理解。这种方式的优势是方便理解;它的劣势是性能比较低。 计算机可以简单的理...

18510

扫码关注云+社区

领取腾讯云代金券