参考伪代码:https://www.processon.com/view/link/62202eb76376892b5b430298
首先说一下读完TLM源码的心得:TLM其实就是一个单向/双向通信的模型,各个函数put/get/write等,可以看做是一个缓存的实现。FIFO就将这些函数封装起来,隐藏IMP的功能。
我看网上有位同学已经将其讲的比较清楚了(相信看完源码就能理解这篇文章了):https://www.cnblogs.com/-9-8/p/7689080.html
本篇文章就把核心代码用伪代码展示出来,简单梳理一下。
uvm_tlm_if_base/uvm_sqr_if_base
TLM端口大体上可以分为两大类:一类是driver和sqr的通信;一类是uvm_component之间的通信。
uvm_port_base
- uvm_port_base其实既不是uvm_component也不是uvm_object。
- 但是在uvm_port_base中有引入一个uvm_port_component,里面大部分的方法实现都是在这个component里面实现的。
- uvm_component的实例化的第二个参数是一级一级传递下来的,所以TLM端口的连接只能是在uvm_component之间实现的!!!!
- 综上:TLM端口其实也在UVM tree上能找到。
- connect:m_provided_by[]/provider[]:表示连接关系。
- m_imp_list[]:表示的imp的关联数组。
resolver_bindings
- resolver_bindings是对应的uvm_root,在end_of_elaboration的阶段,对start_phase进行重载。
- resolve_bindings是自动调用的。
- 最重要的作用就是将m_if从m_imp_list[]中赋值。
端口其实可以分为几大类:uvm_port/export、uvm_imp、analysis_port/export、analysis_imp、tlm_fifo、analysis_fifo
uvm_*port/export
- 指定put函数的调用位置,其实是在imp里面。
uvm_*_imp
- 指定IMP
analysis_port/export/imp
- 跟上面的几乎是一模一样的,唯一的不同就是analysis其实可以支持,一个port连接到多个imp上,所以for循环实现每一个imp的调用。
sqr/driver的连接
- 其实本质山都是跟TLM端口一致的,唯一不同的是函数不同。
FIFO
FIFO,就相当于是一片IMP(也就是相当于一片缓存mailbox),还有两个uvm_analysis_port用于广播。
- uvm_tlm_analysis_fifo 扩展自uvm_tlm_fifo,增加了analysis_export和write的function。