索手锋芒的个人空间 http://blog.eetop.cn/calvin [收藏] [复制] [分享] [RSS]

日志

UVM TLM详解

已有 3705 次阅读2016-9-8 11:47 |个人分类:UVM notebook

TLM中的三种端口

PORT

uvm_*_port #(T)

  *可以由下面任意一个代替:

  • blocking_put
  • nonblocking_put
  •  put
  • blocking_get
  • nonblocking_get
  •  get
  • blocking_peek
  • nonblocking_peek
  • peek
  •  blocking_get_peek
  • nonblocking_get_peek
  • get_peek

    T:The type of transaction to be communicated by the export

    Ports are connected to interface implementations directly via uvm_*_imp #(T,IMP) ports or indirectly via hierarchical connections to uvm_*_port #(T) and uvm_*_export #(T) ports.

uvm_*_port #(REQ,RSP)

    *可以由下面任意一个代替:

  • blocking_transport
  • nonblocking_transport
  • transport
  • blocking_master
  • nonblocking_master
  • master
  • blocking_slave
  • nonblocking_slave
  • slave

    REQ:  The type of request transaction to be communicated by the export

    RSP: The type of response transaction to be communicated by the export

   Ports are connected to interface implementations directly via uvm_*_imp#(REQ,RSP,IMP,REQ_IMP,RSP_IMP) ports or indirectly via hierarchical connections to
   uvm_*_port #(REQ,RSP) and uvm_*_export #(REQ,RSP) ports

EXPORT

与PORT类型相似,同样有与port对应的uvm_*_export #(T)和uvm_*_eport #(REQ,RSP)

IMP

与PORT类型相似,同样有与port对应的uvm_*_imp #(T, IMP)和uvm_*_imp #(REQ,RSP,IMP,REQ_IMP,RSP_IMP)

T: The type of transaction to be communicated by the imp

IMP:The type of the component implementing the interface. That is, the class to which this imp will delegate

REQ:Request transaction type

RSP Response transaction type

REQ_IMP Component type that implements the request side of the interface.Defaults to IMP. For master and slave imps only.

RSP_IMP Component type that implements the response side of theinterface. Defaults to IMP. For master and slave imps only.


TLM的通信

首先是connect,只能有下面几种connection type:


其次要理解控制流和数据流的方向。

控制流: 控制流永远是port到export或imp port的。也就是说,永远去是port作为数据通信的发起者去call put/get等function

数据流:数据流有可能是从port到export/imp port,也有可能从export/imp port到port.

怎么理解呢,如下对比:

component A有uvm_put_port,component B有uvm_put_export,当A call put  task时,数据从A传递到B

component A有uvm_get_port,component B有uvm_get_export,当A call get task时,数据从B传递到A

而不管是put还是get task,都会在component B中进行定义。有点像是A去调了B的task。所以总结起来就是port的task/function都要落到B的task/function上去实现

最后一定注意两件事情:

connect两边的tlm port的type以及transaction type一定要一致,比如blocking_put_port要连接 blocking_put_export或put_export

更需要注意,一定要使用IMP 来终结连接关系, PORT和EXPORT都不能做为连接关系 的终点。

analysis port,analysis export, analysis imp

其实实际运用上,还是最常用analysis  port/imp/export(它们有点像是port/export/imp的增强版,就个人经验来讲完全已经足够了)。主要有以下区别:

  • 一个analysis port可以连接多个analysis export/imp, 也就是说analysis port更像一个广播。
  • analysis port只有一个write function。
  • analysis port没有阻塞非阻塞的区分,它本身只是广播,不必等待其它相连的port的响应。

既然是广播,那么就有可能一个analysis port连接到两个以上的imp,但是write function只有一个,我们怎么办呢?

处理方案:

1.通过宏uvm_analysis_imp_decl声明两个后缀不一样的imp,UVM会根据两个后缀内建两个新的imp

`uvm_analysis_imp_decl(_export1)

`uvm_analysis_imp_decl(_export2)

2.声明 port

uvm_analysis_imp_export1 #(transaction, scoreboard)     scb_imp1;

uvm_analysis_imp_export2#(transaction, scoreboard)      scb_imp2;

3.分别定义两个port的write function

function void write_export1(transaction txn);

function void write_export1(transaction txn);

特别要注意的一点:

analysis port广播出去的是handle,并没有为每一个export/imp的transaction分配alloction,如果如果 export1如果对transaction进行了修改, 那么export2会看到修改后的transaction.所以好的习惯是在write function里面首先 new一个 transaction,并对传输过来的transaction进行copy后,再进行后面的操作。

uvm_tlm_fifo,uvm_tlm_analysis_fifo

顾名思义,uvm_tlm_fifo其实就是能够在tlm肚子里面buffer很多transaction,就像FIFO一样。

有人可能会这样做,我自己在scoreboard里面申明queue,也一样做到fifo的效果。确实,很多情况下,直接把analysis port传过来的transaction放queueu里面,是一个不错的方法。但fifo还有以下几个好处:

1. uvm_tlm_fifo是被动接收数据和被动发送数据,因此可以把发起端和接收端完全分隔开,发数据和收数据的行为完全独立。

2.如果design的transaction有 outstanding,那么uvm_tlm_fifo就直接可以model design的fifo行为了(当然用queue做也不错,甚至碰到out of order的时候比fifo还好用)。

3.通过imp加后缀可以解决多对port,export的情况,但如果port数据多了呢。比如一个有16进16出的AXI interconnect,在scoreboard的port上去申明16个不同名字的imp显然不方便。那么这时候只需要申明一个 uvm_tlm_fifo数组就可以了。(IMP没办法申明数组)

example:

scoreboard:

 uvm_tlm_analysis_export (#sb_item)     in_expor[10];

 uvm_tlm_analysis_fifo(#sb_item)            scb_fifo[10];

 uvm_blocking_get_port #(sb_item)          fecth_port[10];

  ...

  function void connect_phase

    foreach(in_export[i]) begin

      ip_export[i].connect(sb_fifo[i].analysis_export);  

      fetch_port[i].connect(sb_fifo[i].blocking_get_export);

    end

  endfunction


env:

  function void connect_phase

   foreach(mon[i])

    mon[i].op.connect(scb.in_expor[i]);// 为什么要有一个in_export作桥梁,而不直接用mon.op连到scb的fifo呢。可以参考uvm_users_guide 2.3.2,这里不作详细说明

  endfunction

 在soreboard中,不必再去写一个write function和get task了,因为fifo里面已经做了。mon.ap.write直接把数据放到fifo里面,而fetch_port.get直接出fifo头 拿数据。

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

关闭

站长推荐上一条 /2 下一条

小黑屋| 关于我们| 联系我们| 在线咨询 |  EETOP 创芯网 ( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2020-1-30 03:18 , Processed in 0.030341 second(s), 7 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

返回顶部