一、apb_gent的搭建:
apb_agent中包含:driver、sequencer和monitor下文将三者分别讲解,并且封进一个agent中。
1、apb_driver:
首先,uvm_driver是一个参数类,需要对其传输的参数进行讲解,所以先讨论api_item!
item中包含data、addr、cmd和rsp,其中addr可以寻址到rxtx、ctrl、divider和ss寄存器,CTRL和divider寄存器只能进行写操作,并且ctrl寄存器的第七位和31到14位都为0;divider寄存器的31到16位为0,ss寄存器的31到8位为0。
把变量data、addr、cmd、rsp域的自动化,创建。
介绍完传输的参数apb_seq_item之后,就开始介绍真正的driver组件了。
driver中包含两个block一个是reset_block一个是drive_block;
reset_block执行的时候,在复位信号来临的时候,置零所有的信号;
driver_block执行是在复位信号上升沿来临的时候,先拉低psel和penable信号,之后get_next_item,drive_to_dut,对req进行操作后item_done;
drive_to_dut是按照时序操作,先拉高psel,然后就把item中的cmd和addr赋给intf中的端口,在下一拍拉高penable:将item中的data写入pwdata中,还需要在数据传输当拍等待pready信号,如果pready拉高,并且是读操作,把intf中的data赋给item。
2、apb_sequencer:
apb_sequencer中不需要有另外的操作,只需要对sequencer进行注册和创建:注意sequencer也是参数类,并且是继承于uvm_sequencer的组件。
3、apb_monitor:
monitor组件的创建与之前的driver和sequencer基本一致,唯一不一样的就是monitor监测到的数据需要在之后进行广播传输,即到rfm或者scb或者coverage中所以需要定义一个analysis_port,并且在monitor中例化。,检测数据的这一部分,需要在特定的时序:pready拉高时并且penable也为高时(这表明写操作刚刚结束,不为读操作)将intf上的数据赋给item中(cmd、addr,需要注意的时如果cmd为写监测的时pwdata,如果cmd是读监测的是prdata)。
最后将收集好的数据事务item放入port中,调用的是write函数。
4、apb_agent:
agent是uvm组件创建中的最小标准单元:他一般容纳着driver、sequencer、monitor三个组件,并在agent中完成组件的例化以及连接。
在这里多了两处创新的部分:
(1)配置了uvm_active_passive_enum is_active=UVM_ACTIVE;
这个枚举类型中的is_active是用来判断整个agent是active还是passive类型,如果是passive类型则不需要driver和sequencer这两个组件,在agent中也不需要例化和连接了。
(2)配置了analysis_port这处的tlm使用是避免我们在使用其他工程师编写的vip时,跨层次使用,或者发生端口消失代码报错的问题,也是方便后续复用。
在connect中需要将monitor中的port与agent中的port相连接,以及将driver和senquencer中的隐含port连接。
二、apb_sequence:
这里介绍一些最基础的sequencer,我们后续的apb端发送激励是通过rgm来发送。
1、apb_bae_sequence:
2、读写sequence: