书接上回:
从零开始搭建UVM平台(一)-只有uvm_driver的验证平台
从零开始搭建UVM平台(二)-加入factory机制
从零开始搭建UVM平台(三)-加入objection机制
从零开始搭建UVM平台(四)-加入interface
从零开始搭建UVM平台(五)-加入transaction机制
从零开始搭建UVM平台(六)-加入env
从零开始搭建UVM平台(七)-加入monitor
从零开始搭建UVM平台(八)-加入agent
从零开始搭建UVM平台(九)-加入reference model
从零开始搭建UVM平台(十)-加入scoreboard
从零开始搭建UVM平台(十一)-加入field automation机制
加入sequence机制
为什么要加入sequence机制?前面driver里例化了transaction,并将trasaction驱动到了总线上,为了使driver的职责变得更加清晰明了,便只让driver完成驱动数据这一个任务,那么创建transaction的任务由谁来完成呢?答案就是sequence机制。
Sequence机制包含了sequence和sequencer。前者可以理解为是一系列的transaction构成一个sequence,因此它本质是一个uvm_object,它的职责是例化一系列transaction并随机化;而后者是一个uvm_component,负责将sequence例化的transaction发送给driver。
在加入sequence机制前,首先要想清楚平台结构的变化以及一些关键注意事项。
第一点:创建sequencer。首先,Sequencer属于component,因此直接继承uvm_sequencer后需要用uvm_component_utils宏进行注册。其次,她负责将sequence产生的transaction传递给driver,那么在创建类时必须是参数化类,其中的参数就是要传递的transaction的类型,同时还要修改driver为参数化类,参数类型是从sqr那边接收到的transaction的类型。修改driver为参数化类有一个好处是可以直接调用在uvm_driver里已经定义好的一个变量req,这个req的类型就是driver的参数化类型。
第二点:需要在agent例化sequencer。
第三点:搭建sqr和drv的transaction通道。前面说过,uvm里实现component之间transaction级别的通信靠的是TLM机制。但是这里不需要自己创建port了,因为uvm_driver里已经定义好了一个port叫seq_item_port,而uvm_sequencer里也已经定义好了一个export叫seq_item_export,那么只需要在agent里将这两个port连接起来即可。
第四点:driver向sqr中拿到transaction。前面port通道已经搭建好了,那么接下来driver怎么向sqr索取transaction?靠的是get_next_item()函数,需要注意的是,driver驱动完成之后,还需要调一下item_done()函数来告知sqr driver已经收到了这笔transaction,这是一种通信握手机制。
第五点:创建sequence。Sequence前面说了它的职责就是例化一系列transaction并随机化。那么它是如何完成这个功能的呢?需要实现一个body函数,并且在body函数里调用`uvm_do宏就可以了。只要调了`uvm_do宏,例化并随机化transaction的动作便会自动完成。
第六点:何时启动seq?只有seq启动了,才能产生transaction并传递给driver。只需要在例化seq之后调用一下seq的start函数。注意在调用start函数时,要给它传入一个参数,这个参数就是seq要传递到的sqr。同时在start函数前后要raise_objection/drop_objection。