UVM(5)sequence

如何启动

  1. default sequence会自动调用start
  2. 先例化再用default

sequence执行的函数

如何仲裁

UVM支持同一时刻在同一sequencer上启动多个sequence。

  1. uvm_do_priuvm_do_pri_with的第二个参数是优先级,这个数值必须是一个大于等于-1的整数。数字越大,优先级越高
  2. 设置仲裁算法env.i_agt.sqr.set_arbitration(SEQ_ARB_STRICT_FIFO);

默认情况下sequenc1er的仲裁算法是SEQ_ARB_FIFO。它会严格遵循先入先出的顺序,而不会考虑优先级。
SEQ_ARB_WEIGHTED是加权的仲裁;

SEQ_ARB_RANDOM是完全随机选择;

SEQ_ARB_STRICT_FIFO是严格按照优先级的,当有多个同一优先级的sequence时,按照先入先出的顺序选择;

SEQ_ARB_STRICT_RANDOM是严格按照优先级的,当有多个同一优先级的sequence时,随机从最高优先级中选择;

SEQ_ARB_USER则是用户可以自定义一种新的仲裁算法。

再sequence使用lock

类似PV操作

或者用grab。grab操作比lock操作优先级更高

lock请求是被插入sequencer仲裁队列的最后面,等到它时,它前面的仲裁请求都已经结束了。grab请求则被放入sequencer仲裁队列的最前面,它几乎是一发出就拥有了sequencer的所有权

失效sequence

UVM提供措施使sequence可以在一定时间内不参与仲裁,即令此sequence失效。

sequencer在仲裁时,会查看sequence的is_relevant函数的返回结果。如果为1,说明此sequence有效,否则无效

实现如下即可

还有一个函数也有关

is_relevant与wait_for_relevant一般应成对重载

当sequencer发现在其上启动的所有sequence都无效时,此时会调用wait_for_relevant并等待sequence变有效

相关宏实现

uvmdo

uvm do隐含指定sequencer为 m_sequencer,这个m sqr就是此sequence启动时为其指定的sequencer

我们可以实现pre、mid、postdo来完善uvmdo

pre_do有一个参数, 此参数用于表明uvm_do宏是在对一个transaction还是在对一个sequence进行操作

mid_do和post_do的参数是正在操作的sequence或者item的指针, 但是其类型是uvm_sequence_item类型。 通过cast可以转换成目标类型( 示例中为my_transaction) 。
 

uvmsend

还有一种方法如下

`uvm_create(m_trans)  例化trans  等价于m_trans = new("m_trans");

`uvm_send(m_trans)  发送出去

还可以这样uvm_send_pri(m_trans, 200)

此send可对trans随机化,前提是trans已被例化

不使用宏实现

  1. 例化trans

随机化可以在例化后进行

设置优先级

高级用法

seq的嵌套

除了uvm_do宏外, 前面介绍的uvm_send宏、 uvm_rand_send宏、 uvm_create宏, 其第一个参数都可以是sequence的指针。

唯一例外的是start_item与finish_item, 这两个任务的参数必须是transaction的指针。

注意也可以在内层seq定义rand变量,不要和item定义同样的名字。

然后随机化

transaction类型的匹配

一个seq只能存在一个trans或者是他的派生

上述嵌套sequence的前提是, 在套里面的所有sequence产生的transaction都可以被同一个sequencer所接受
那么如何使两个不同的trans在 一个seq使用呢?

将sequencer和driver能够接受的数据类型设置为uvm_sequence_item:

然后

这样把两个不同的seq包裹在uvmseq中,变成爹了。如此使用子类变量需要cast

p_sequencer

`uvm_declare_p_sequencer(my_sequencer)
之后UVM之后会自动将m_sequencer通过cast转换成p_sequencer

因为msqr继承爹,myseq不可以访问myseqr的变量,所以要么cast msqr,要么用psqr

virtual sequence

它根本就不发送transaction, 它只是控制其他的sequence, 起统一调度的作用。


为了使用virtual sequence, 一般需要一个virtual sequencer。 virtual sequencer里面包含指向其他真实sequencer的指针:
 

base_test中, 实例化vsqr, 并将相应的sequencer赋值给vsqr中的sequencer的指针:

在virtual sequene中则可以使用uvm_do_on系列宏来发送transaction

如此先在vseq中声明两个seq,然后do on在vseqr中的sqr0、1.其中tr也在sqr0中do。

virtual sequence作为一种特殊的sequence, 也可以在其中启动其他的virtual sequence:

如何控制objection

在引入virtual sequence后,我们就不用在sequence中控制objection了,一般来说, 只在最顶层的virtual sequence中控制objection。

使用configdb

对sequence使用config时有一个点是不方便使用路径、因为他不在uvm树中

uvm_config_db#(int)::set(this, "env.i_agt.sqr.*", "count", 9);
于是我们可以如此操作,直接把路径设置为sqr。用*是因为无法确定例化的seq是什么名字。

uvm_config_db#(int)::get(null, get_full_name(), "count", count)
在get函数原型中, 第一个参数必须是一个component, 而sequence不是一个component,所以这里不能使用this指针, 只能使用null或者uvm_root::get( ) 。

前文已经提过, 当使用null时, UVM会自动将其替换为uvm_root: : get( ) , 再加上第二个参数get_full_name( ) , 就可以完整地得到此sequence的路径, 从而得到参数。

set

uvm_config_db#(bit)::set(uvm_root::get(), "uvm_test_top.env0.scb","cmp_en", 0);

除了向component中传递参数外, 也可以向sequence中传递参数:
uvm_config_db#(bit)::set(uvm_root::get(), "uvm_test_top.v_sqr.*", "first_start", 0);
 

等待db配置

第一句会阻塞,直到cmp_en 变化

与get函数一样, 除了可以在一个component中使用外, 还可以在一个sequence中调用wait_modified任务
 

response

sequence需要得到driver的一个反馈。driver用put,seq用get

关键是设置set_id_info函数, 它将req的id等信息复制到rsp中。 足以区分是哪个response

uvm还支持seq_item_port.item_done(rsp);
 

多次返回

多次调用即可,但是不可以用rsp作为done的参数了

默认队列最大为8

解决阻塞

若driver需要延时较长的一段时间才能将transaction传回,希望能够继续从sequence得到新的transaction并驱动它, 但是由于sequence被阻塞在了那里, 根本不可能发出新的transaction。

需要使用response_handler:

然后在重载

首先将其通过cast转换变成my_transaction类型, 之后就可以根据rsp的值来决定后续sequence的行为
无论是put/get_response或者response_handler, 都是新建了一个transaction, 并将其返回给sequence
 

rsp与req类型不同

就要传两个参数

sequence library

它根据特定的算法随机选择注册在其中的一些sequence, 并在body中执行这些sequence。

起名、初始化、注册seq

也可以一个sequence在定义时使用宏uvm_add_to_seq_lib来将其加入某个sequence library中:

一个seq也可以加入不同的lib

library定义好后, 可以将sequence library作为sequencer的default sequence:

UVM会随机从加入simple_seq_library的sequence中选择几个, 并顺序启动它们。
 

lib运行顺序

UVM_SEQ_LIB_USER是用户自定义选择的算法。 此时需要用户重载select_sequence参数

运行次数

library会在min_random_count和max_random_count之间随意选择一个数来作为执行次数

一起配制

UVM提供了一个类uvm_sequence_library_cfg来对sequence library进行配置。 它一共有三个成员变量:

我们只需要

或者

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值