UVM和System verilog笔记总结

UVM是一个方法,是一个平台。UVM-1.2平台提供了:
uvm_test/env/sequence/sequencer/driver/monitor/agent、
base/comp/tlm/seq/ral/
'uvm_fatal/error/warning/info/object_utils/component_utils(extends使用时需要注册)
uvm_port/socket/sequence_item/transaction
这些libraries库

UVM的组成:
component(功能仿真算法等)、communication(通信TLM,port,export、fifo)、transaction(数据定义)
component由uvm_test/env/sequence/sequencer/driver/monitor/agent组成;
communication通信由uvm_port和uvm_socket组成;
transaction的数据定义传输由uvm_sequence_item组成。在这里插入图片描述
以uvm_test为test文件的基类,uvm_driver为命令解析的基类,uvm_monitor为命令采集的基类
uvm_sequence和uvm_sequencer为激励的基类,uvm_agent为协议的基类等,不同的接口用不同agent
interface则是一个SV写法的接口定义

static不能定义virtual虚拟定义的class
引用static的要用双冒号::调用class_name::function,静态解析符

Singleton class 用static定义的属性,没有new(),没有if,没句柄。
Singleton object 只使用一个静态的对象, 有new()、if。

virtual class里面只有virtual function,虚态的属性

CDV覆盖的驱动验证(Coverage-Driven Verificaition)

registry 注册表
覆盖率的途径有line、expression、FSM(状态机)、triggle(触发器)、path(这个为主)

UVM里面的class必须写在program里面,然后在initial调用

更高的覆盖率,更简洁的代码。
测试层、场景层、功能层、命令层、信号层(五个层次)。

component的phase主要由7个机制组成:
build phase/connect phase/run(reset、configure、main、shutdown)phase
在这里插入图片描述
机制的意义是什么?
答:多个testcase运行当中有时候需要同步进行,而这些机制的运行,是按照一定顺序进行。

一般在component和transaction里进行拓展编写, sequence_item


下面举例一个简单的test,首先调用uvm_test

class要写在program里
注册一个class,
然后在run_phase里面写操作,
接着用initial调用跑,不能直接跑,
就这样写好了,输出的结果是“Hello UVM”

test-testcase(uvm_test)-environment(uvm_env)-agent(sequence、driver、monitor)-transaction这是流程
在这里插入图片描述

在task里写功能层,不可在function写,function是一个函数的行为级


仿真时候用vsim test —+ UVM_TESTNAME = WHAT


但一般的test没这么简单,而是:
在test里面写environment的class,type id::create()构造

注意是在build_phase virtual function里构造:env = environment::type id::create(‘env’,this);

test_case调用envrionment env,开始envrionment env调用component
从而形成一个完整的调用过程。

上面提到的build_phase是我们之前讲的component的phase7个主要机制组成的第一个
在这里插入图片描述

在build_phase里面写的phase从上到下先执行,再其他的phase从下至上执行。
并行功能性的写在run_phase里面
在这里插入图片描述

所有以uvm开头的基类拓展的类需注册
uvm_component_utils(new_test_base)


testbench由以下组成:
test-testcase(uvm_test)-environment(uvm_env)-agent(sequence、driver、monitor)-transaction(处理)写agent- TLM连接
TLM-Transaction Level Modeling 是传输模型,component里,port/export/fifo等串口的传输
在这里插入图片描述
工厂factory模式,用override替换新的driver、类似是一个新驱动,全都改变

transaction差不多就是打包了(address=A、data=5、op=write)的传输
下面是transaction的使用过程:
1)sequencer写的items(transaction)传输给driver,(address=A、data=5、op=write),用interface送给DUT
2)DUT传给monitor然后在Scoreboard查看传输情况
testcase-sequencer-driver-DUT-Scoreboard

二值逻辑的初始值是0,四值逻辑的初始值是x。

写transaction的时候,第一不要写错父类,第二一般有rand随机属性,补充:随机可关(mode=0)

使用new_transaction:
先注册一个transaction,来自uvm_sequence_items
'uvm_object_utils_bgein(transaction)
再使用transaction的时候create该句柄
tr=transaction::type_id::create(“tr”,this);

如何改变约束
close the constraint;
tran tr;
tr=new();
tr.randomize with 100; ##使约束值为100

constrain是约束:
constrain rule{
len in {100,200};
}

pack用于打包传输一串数据;upack用于解包
宏定义的方法使用
tr0.copy(tr1);tr0.print();
$cast(tr1,tr0.clone);
tr0.pack(bit_stream);
tr0.unpack(bit_stream);

post_randomize()是指随机函数,自动执行。

问题:突然想对其中的一个data取消print,packed,unpack系列等其他的操作,如何做?
回答:注册注销,注销宏定义,或者重写do_pack函数


接下来要对component的的组成进行详细描述,首先是sequence

uvm_sequence产生随机数基类,用sequencer传送改写的sequence给driver,最后到DUT。

call sequence’start() method调用指定的sequence。

一个agent由agent、sequence、sequence_item、sequencer、driver五部分组成

下面详细讲解一下sequence的写法,sequence是对随机数据的激励

在这里插入图片描述

sequence在task body()函数里面写rand激励,写响应。phase raise开启、drop结束。req的class是传参的句柄

多个sequence的使用:在这里插入图片描述
sequence_item(transaction)产生数据格式,用sequencer将sequence的随机数据格式的对象送给driver,最后到DUT。

在这里插入图片描述
上面的sequencer做到了注册的作用,而真正的启动sequence和driver之间的通信,还是需要下面的启动方式。

一:start函数,调用phase.raise_objection和phase.drop_objection。
二:config_db # default_sequencer

在这里插入图片描述
在test.top里面启动sequencer。

写完sequencer写driver(uvm_driver),里面有run_phase(),driver用于解析送过来的sequence(transaction),run_phase起来 forever

在这里插入图片描述

写完driver写通信,下面是sequencer和driver的通信,用TLM通信。圈圈里面的是sequencer。
-在这里插入图片描述


下面是test里面由多个sequences,写environment class利用
uvm_config_db #(uvm_object_wrapper)::set(this,".seqr.main_phase"“default_sequence”,transaction_sequence::get_type());
使得sequence连接对应的
.seqr.main_phase;

或者先null,再重新写进去(不推荐)
在这里插入图片描述
uvm_config_db #(int)::set(this,“env.agent.seqr”,“port_id”,12); #还可以用来传递参数
phase —变量类型 ----赋值 ------- 路径 -------------端口--------值

seq_phase::set(this.“env.seqr.configure_phase”,“default_sequence”,“seq_CFG::get_type()”)
来配置sequence的phase
configue_db是跨class的配置。一般组合set和get


届时还要写一个agent class;
agent编写connect函数将sequencer和driver连接起来,
先create定义句柄,然后connect两者,
在这里插入图片描述
randc所有的随机值实现一遍

提到message,其由none、low、medium、high,full、debug选择输出次数
“%m”显示要执行的层次,用在UVM_HIGH里面:在这里插入图片描述

#()表示传输的参数的类型


component的configuration用来配置数据和string:
uvm_config_db #(type)::set(this,“name”,“if”,dut_test_top.if) ##亦或uvm_resource_db #(type)::set(this,
uvm_resource_db #(type)::set(this,“name”,“if”,dut_test_top.if)

component由7个机制phase组成,build、connect、run(reset、configuration、main、shutdown)

set和get最好都写。

一个new_testbench的例子:
driver/monitor class --》environment class–》testbench class

先注册一个transaction(sequence_item),
'uvm_object_utils_begin(transaction)
再virtual task 的body()
的construct里agent的create句柄
tr=transaction::type_id::create(“tr”,this);

对transaction_new或component旧的内容修改,不可用new(),而是用override进行新建驱动和数据类型

set_type_override_by_type(transaction::get_type(),new_trans::get_type());或者
set_inst_override_by_type("*.path",transaction::get_type(),new_trans::get_type());改路径
此时完成了对transaction的修改
当然,driver也可以

实现factory机制(实现test)三步骤:
先注册class(extends),后create::type,
再set_inst_override_by_type(driver::get_type(),driver_2::get_type(),“uvm_test_top.t_env.ag1.drv”);
将driver更替为driver_2
这样就能修改内容,调用的时候改变。

四种class override:
set_inst_override_by_type();
set_type_override_by_type();
set_inst_override_by_name();
set_type_override_by_name();


为什么uvm提供factory机制?
答:重新写一个组件,一般来说,testbench写完后不能改,在需要修改driver、monitor的时候
重写override来替换,实现新的需求;第二个,插入errer_testcase,重改,重写transaction。
哪些class有factory机制?
答:uvm_component :driver、monitor、agent、transaction

如何实现factory机制?
一:注册 uvm_object_utils and uvm_component_utils(transaction type component type);
二:create::type,class需要调用,分配对象;
三:写新的transaction_da_3,用set_type_override_by_type;或者set_inst_overrid e_by_type;完成override的替换(即factory机制)
在这里插入图片描述
实现新的transaction_da_3的时候,extend的是原来的transaction;
老driver如下:
在这里插入图片描述
新driver如下:
在这里插入图片描述
用factory机制替换,
在这里插入图片描述

create 和 new()分配一个对象的问题?
用create对象句柄,修改driver、monitor这种。而new()无法使用factory的机制,

config_db机制配置的方法?两种?

config_机制由上层set到底层,配置interface/object/class等传输,如:set string—》filed name
uvm_config_db #(type)::set(this,“name”,“if”,dut_test_top.if) local configuration
uvm_resource_db #(type)::set(this,“name”,“if”,dut_test_top.if) global configuration

set配合get,使得在env里面对下面的参数进行配置。
在这里插入图片描述

什么时候只需要::set,不需要::get?
注册变量之后,可以不需要::set

可以使用uvm_top.print_topology()查看修改后的情况

在这里插入图片描述
和factory.print()进行查看
在这里插入图片描述

  • 1
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值