UVM入门和进阶实验4

 实验4 中完成以下内容

  1. 将产生transaction 并且发送至driver的generator 组件,拆分为 sequence与sequencer

  2. 在拆分的基础上,实现底层的 sequence。

  3. 完成sequencer与driver 的连接和通信工作

  4. 构建顶层的 virtual sequencer。

  5. 将原有的 mcdf_ base_test拆分为mcdf_base_virtual_sequence与mcdf_base_test前者发挥产生序列的工作,后者只完成挂载序列的工作。

  6. 将原有的 mcdf_data_consistence_basic_test和mcdf_full_random_test继续拆分为对应的virtual sequence和轻量化的顶层test.
    ……………………………………………………………………………………………………………………………

    由于上述要求均是整体服务于我们的最终目标,即将generator、driver 与 test 的关系最终移植为sequence、sequencer、driver和 test 的关系,可谓是一个完整的移植过程,因此我们本实验的目标聚焦为sequence的使用。

一、知识巩固复习

1. start()和`uvm_do的区别

  1. seq.start(e.sqr)用来将sequence挂载到sequencer上面,用于在给定的序列器上启动序列。例如,如果您 有一个名为seq的序列对象和一个名为sqr的序列器对象,您可以使用以下代码来启动序列: seq.start(sqr); 这样,seq序列将在sqr序列器上启动
  2. `uvm_do宏用来在内部的child_sequence中使用,而uvm_do是一个宏,用于简化序列启动的语法。例如,如果您有一个名为seq的序列对象,您可以使用 以下代码来启动序列: `uvm_do(seq) 这样,seq序列将在当前上下文中的默认序列器上启动。

2. uvm_do_with宏,这个宏完成了 三个步骤(漫游P373): 

  1. sequence 或 item 的创建;
  2. sequence 或 item 的随机化
  3. sequence 或 item 的传送

常用在sequence的send_trans中,代替了type_id和randomize

3.宏`uvm_do_on(SEQ_OR_ITEM, SEQR)

        `uvm_do_on用于显式地指定使用哪个sequencer发送此transaction。它有两个参数,第一个是transaction的指针,第二个是 sequencer的指针。当在sequence中使用uvm_do等宏时,其默认的sequencer就是此sequence启动时为其指定的sequencer,sequence将这个sequencer的指针放在其成员变量m_sequencer中。

二、实验部分

实验1.1:driver与sequencer的改建

实验要求:移除原有在各个driver 中的 mailbox 句柄,以及在 do_driver0任务中使用mailbox句柄通信的方式,转而用uvm_driver::seq_item_port进行通信。同时,请定义对应的uvm_sequencer.

在chnl_pkg中,chnl_driver如下(fmt_pkg, reg_pkg中均类似)

实验1.2:底层sequence的提取

实验要求:

请将原来在各个generator 中发送transaction 的任务,提取为各个对应的底层sequence。这里需要特别注意,将 mcdf _base_test中的idle_reg()、write_reg()和read_reg()也可以提取并在reg_pkg 中定义为对应的 sequence,即idle_reg_sequence、write_reg_sequence和 read_reg_sequence。

chnl_pkg中fmt_generator替换成fmt_config_sequence,(fmt_pkg, reg_pkg中均类似)

对于上述代码中 uvm_sequence::get_response(RSP)

在完成驱动后,driver 应当通过 item_done()来告知 sequence 已经完成数据传送,而 sequence 在获取该消息后,则表示 driver 与 sequence 双方完成了这一次 item 的握手 传输。在这次传递中,driver 可以选择将 RSP 作为状态返回值传递给 sequence,而 sequence 也可以选择调用 get_response(RSP)等待从 driver 一侧获取返回的数据对象

idle_reg_sequence、write_reg_sequence和 read_reg_sequence

在mcdf_pkg中存在generator,所以需要调用reg_gen.start()等,而当改编成sequence后,任务的创建随机化发送可以由`uvm_do_with等宏完成。

约束块里赋值用" == ",不用" = "的原因(书sv_P156)?

因为在约束块里只能包含表达式,所以在约束块里不能进行赋值。相反,应该用关系运算符为随机变量赋一个固定的值,例如len == 42,也可以在多个随机变量至今啊使用更复杂的关系表达式,例如len == header.addr_mode*4+payload.size()。


实验1.3:sequencer的创建和连接

实验要求:

在各个agent 中声明、创建对应的 sequencer,并且将其与driver 通过 TLM port连接起来。

chnl_agent具体内容如下,其他类似

漫游P374页,关于端口连接的解释:

实验1.4:移除 generator 的踪迹

实验要求:

generator这个SV实验阶段的历史产物,就要从我们的验证结构中清除了。请在mcdf_base_test 中移除它们的声明、创建以及和driver 之间的连接

移除了跨层次的句柄连接,之前是在agent和generator中实现句柄连接,但是到了uvm中,引入了sequencer后,sequencer和driver以及monitor三者合并在agent中,因此在一个组件内实现了连接,顶层test不需要连接了

实验1.5:移除uvm base test的transaction 发送方法

实验要求:

请将已经被从uvm_base_test 移植到reg_pkg 中的方法idle_reg0、write_reg0和read_reg0从uvm_base_test 中移除。由此可以看到,uvm_base_test 只变为了容器的性质,在它内部主要由 mcdf_env、将来添加的 mcdf_config 配置对象以及被用来挂载的顶层sequence构成。

都应移除

实验1.6:添加顶层的 virtual sequencer

实验要求:

由于 MCD 验证环境中存在多个底层的 sequencer和 sequence,因此这就需要有顶层的virtual sequencer 与virtual sequence统一调度,可以参考红宝书13.5.2节。请实现MCDF的顶层virtual sequencer。

实验1.7

实验要求:

在定义了mcdf_virtual_sequencer 之后,请将其在 mcdf env中声明、例化,并目完成其与底层sequencer的句柄连接

声明:

例化:在(build_phase中)

句柄连接:(在connect_phase中)

实验1.8:重构mcdf_base_test

实验要求:

原有的 mcdf_base_test 除了承担其容器的功能,还在其run_phase 阶段中实现了sequence的分阶段发送功能。我们在添加了顶层的virtual_sequencer 之后,需要将所有发送序列的顺序和组织等内容均移植到mcdf_base_virtual_sequence,因此需要将mcdf_base_test::run phase()发送序列的功能移植到新定的 mcdf_base_virtual_sequence一侧,而在移植后,mcdf_base_test::run_phase()只需要挂载对应的顶层 virtual sequence 即可。

结合实验1.2对比学习

修改之前的mcdf_base_test中 run_phase内容如下:

修改之后的内容以及相应的run_phase如下:

实验1.9:重构mcdf_data_consistence_basic_test

实验要求:

在理解了 mcdf_base _test与mcdf_base_virtual_sequence 的关系之后,我们可以继续重构mcdf_data_consistence_basic_test,将其产生和发送transaction 的任务,均移植到mcdf_data_consistence_basic_virtual_sequence,而进一步减轻mcdf_data_consistence_basic_test 的体重。由此大家需要加深认识,即测试的动态场景往往是由 virtual sequence统一组织的,而test 层往往之后做run phase 前的一些验证环境的配置

拆分之后的代码对比如下:

实验1.10:重构mcdf_full_random_test

实验要求:

可以继续参照实验1.9 的要求,也将mcdf_full_random_test 的内容重构为mcdf_full_random_virtual_sequence和 mcdf_full_random_test.

修改之前的代码:

修改之后的代码:

三、 常见问题

1. m_sequencer和p_sequencer有什么区别?

`uvm_declare_p_sequencer(mcdf_virtual_sequencer)

主要是在sequence中使用,其实主要作用类似就是把sequence挂载到sequencer中,或者说联系起来,哪个sequence和sequencer相关。

因为经常用到父类 $cast 转换为子类,因此特意定义了一个这样的宏,用来转换这个。

2. `uvm_do系列宏相关介绍

`uvm_do系列宏

常用在uvm_sequence中,uvm_do系列的宏主要用于序列(sequence)的生成和发送。这些宏可以简化代码,避免在代码中反复调用start_item()和finish_item()等方法

四、 实验结构分析

各类package包含的内容

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值