New 与 ::Type_id::create的区别(详见工厂机制)
UVM推荐使用内置方法 :: type_id :: create() ,而不是直接调用构造函数new()创建组件或事务对象。create方法在内部调用factory机制以查找所请求创建的类型,然后调用构造函数new()以实际创建一个对象而 无需更改任何代码 。
sequence_item,sequence,sequencer,driver之间的关系
sequence_item(封装):只对数据进行封装,不存在自动执行的函数;
sequence(生产):具有可自动执行的body()函数,产生数据激励;
当sequence的start的函数启动,sequence会执行body方法,产生事物,并将事物发送给sequencer放入FIFO中储存。Sequence会等待一个driver的完成响应,得到之后会退出该次事物的产生。
sequencer(发送):将数据发送给driver;
当sequencer启动时,首先会检查自身的default_sequence是否配置,如果配置了就会创建实体,设置该sequence的starting_phase并随机化该sequence。最后调用sequence的start()函数启动该sequence。
driver(请求):向sequencer发送事务请求,处理完成后,返回一个响应;
首先向sequencer发送一个事物请求,然后等待事物,sequencer会将产生好的事物发送给driver,driver在处理完该事物后,返回一个完成响应。
启动方式
直接启动:调用start()方法;
隐式启动:通过uvm_config_db 配置 default_sequence启动;(本质上还是调用start)
通信机制
(1)在sequence中放sequencer的句柄,在sequencer中放sequence的句柄,进行sequence与sequencer的“双向握手”;
(2)利用TLM机制进行driver、sequencer的握手。下文会对握手机制进行深入的剖析。
注:
用户自定义的transaction,是拓展自uvm_sequence_item这个类的。用户自定义的sequence是拓展自uvm_sequence的,而uvm_sequence又是从uvm_sequence_item拓展的。
1.driver发送request给sequencer;
2.sequencer把request数据发送给driver;
3.driver处理数据;
4.处理完成后,driver发送done给sequencer;
仲裁机制
UVM默认先入先出的仲裁机制;
多个sequence搭载同一sequencer时,可以通过设置仲裁算法或sequence的优先级改变;
通过lock(排队),grap(插队),unlock,ungrap实现sequencer的独占;
通过is_relevant和wait_for_relevant,使sequence失效;
m_sequencer与p_sequencer的区别
uvm_sequencer_base是例化在uvm_sequence_item中的,而任何sequence都是从uvm_sequence_item拓展的,因此,在sequence中就可以调用uvm_sequencer_base中定义的task。这就实现了“在seq中调用sequencer”的机制
m_sequencer是uvm_base_sequencer类型的句柄,定义在uvm_sequence_item中,其本质是item/seq和sequencer之间交互的桥梁。
p_sequencer
- 声明了一个sequencer类型的句柄p_sequencer
- 将m_sequencer句柄通过$cast(p_sequencer,m_sequencer)转化为p_sequencer 类型的句柄。
`uvm_declare_p_sequencer(SEQUENCER_NAME)
m_sequencer是uvm_sequencer_base类型的句柄,默认情况下在uvm_sequence中可用。但是要访问在真实的sequencer,我们需要对m_sequencer进行转换(typecast),通常称为p_sequencer。
sequence类里有一个uvm_sequencer_base类型m_sequencer指针,当sequence和sequencer关联后,m_sequencer会自动指向该sequencer,但通过m_sequencer不能直接使用seqr里的变量,否则会出现编译错误。只能使用cast强制向子类转换后,才能通过m_sequencer.xxx来访问该seqr内的xxx变量。
Virtual sequencer的作用
virtual sequence是一个包含和执行多个子sequence的容器,virtual sequencer是包含其他sequencer的容器以使得virtual sequence中的每个子sequence都能在相应的sequencer上获得执行。
virtual sequence是控制多个sequencers中激励生成的sequence。由于sequences sequencers和drivers都只针对单个接口,几乎所有测试平台都需要virtual sequence来协调不同接口之间的激励。Virtual sequences在子系统或系统级测试平台上也很有用,可以使模块级的sequence协调地运行。