乐于分享
好东西不私藏

[UVM源代码研究] TLM里的各种port、export、imp使用研究

[UVM源代码研究] TLM里的各种port、export、imp使用研究

TLM里的各种port、export、imp连接时必须要严格配对使用。

uvm_block_get_port必须要连接到实现了get算法的imp上去,并且调用的通信算法必须是get(task),因为源代码里对类uvm_block_get_port里面的通信方法已经规定死了,如下图所示:

下图为port相关的几个类的定义

UVM_PORT_COMMON宏的定义:

UVM_BLOCKING_PUT_IMP宏的定义:

可以看到对应的port中定义了put方法,并且调用该put方法时会去调用该port连接的imp所在类里的put方法(一般会被重写,除非是uvm标准类库里已经实现的)

对应的imp中的源代码:

内部也实现了一个put的task

那么问题来了,能否把一个put_port连接到一个get_imp上?

是否可以认为initiator确定了调用的通信方法,imp只需要在target端实现对应的通信方法,至于是什么imp只需要保证task/function符合要求就行了

错!不能

原因是:initiator中的port调用的通信方法从源代码看会在该port中声明,相应的target中的imp里也会有对应的通信方法的声明,如下图所示:

该imp会去调用target里实现的对应的通信方法!

那么问题来了,如果

用一个put_port跟一个get_imp进行连接

,那么

initiator中调用的是put方法,而get_imp中需要target中实现get方法,否则就报找不到get方法的error,就是上面截图的223行

那么我们做个极端的假设,

把一个put_port连接到一个get_imp上,我们在target端同时实现了put和get方法

,能通过put方法进行通信吗?

仿真结果仍然报错

报错内容在如下源代码:

我们看看关于connect这个函数的描述:

关键就在这边会做PORT类型(所谓的interface compatible)匹配的检查

关于这个

m_if_mask

的定义是在PORT定义里的new函数里赋值的,如下图所示:

这个

MASK

的值,就是在调用宏的时候赋值的,以uvm_blocking_put_port为例:

对应的MASK的值就是

`UVM_TLM_BLOCKING_PUT_MASK

再次查看uvm_imps里的源代码就会发现,只有uvm_blocking_put_imp的传递的宏与之相同

这就决定了

能够与uvm_blocking_put_port相连的imp只能是uvm_blocking_put_imp或者其子类

进一步查看该MASK宏的定义:

所以一旦initiator里的PORT确定了,那么target里的IMP也基本就确定了,

源代码中约束了通信方法以及配对的PORT与IMP格式

总结

1、不同组件之间进行通信时的需求决定了所需port/imp对的类型

    • 需要阻塞那就需要选择blocking的PORT对
    • initiator是producer还是consumer决定了通信方法选择用put(阻塞)/try_put(非阻塞)还是get/try_get
    • 如果是一对多的情况就得用analysis_port/analysis_imp,对应的通信方法就是write

2、确定了port/imp对之后就在initiator中调用通信方法,在target中实现通信方法

本站文章均为手工撰写未经允许谢绝转载:夜雨聆风 » [UVM源代码研究] TLM里的各种port、export、imp使用研究

评论 抢沙发

9 + 2 =
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
×
订阅图标按钮