路科验证的个人空间 https://blog.eetop.cn/1561828 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

UVM通信篇之五:TLM2通信

已有 3484 次阅读| 2018-1-28 13:42 |个人分类:验证系统思想|系统分类:芯片设计

在本章之前的部分中,读者们认识了TLM是一种为了构建更高级抽象模型的传输方式。虽然SV语言本身没有原生TLM的传输方式,但是它在UVM中很好地集成进来了并且也充分在各个组件传输中运用了进来。在这里,需要注意的是,各个组件之间的通信是通过TLM1.0的方式实现的。而伴随着SystemC模型的广泛引用,SystemC的主要通信机制TLM2.0也引起了UVM标准委员会的广泛兴趣。


我们之前介绍过TLM协议本身并不依赖于某一种语言,而可以跨语言地完成它的传输标准。TLM2.0是SystemC的模型之间的核心传输方式,它在2009年发布,并随后成为IEEE的标准IEEE-1666-2011。与TLM1.0相比,TLM2.0的提供了一些更丰富的特性,它们主要包括:

  • 双向的阻塞或者非阻塞接口

  • 时间标记

  • 统一的数据包


通过这些更加一致和丰富的特性,使得接口之间的通信接口更趋于标准,并且更容易构建更抽象的模型。虽然TLM2.0一开始作为SystemC标准库的一部分(由C++实现),但是RTL与SystemC模型的混合仿真趋势,要求SystemVerilog也能够有与之匹配的接口便于日后的互相嵌套。所以我们本节将重点介绍TLM2.0的若干特性、它们在UVM中的实现方式以及通过一些例码为读者们介绍它们的使用方式。


接口实现

TLM2.0的传输是双向的,即意味着在一次完整的传输中有request和response类型。这么听起来,似乎和我们在TLM1.0中的transport接口时类似的。先别急着下结论,TLM2.0首先支持blocking和nonblocking两种transport方式。

  • blocking的传输方式要求在一次传输过程中,完成request和response的传输。

  • nonblocking的传输方式则将request和response的传输分为了两个独立的单向传输,而整体完成了一次完整传输。


上面的两种传输方式对应的SV的方法如下:

task b_transport(T t, uvm_tlm_time delay);

function uvm_tlm_sync_e nb_transport_fw(T t, ref P p, input uvm_tlm_time delay);

function uvm_tlm_sync_e nb_transport_bw(T t, ref P p, input uvm_tlm_time delay);


这里T代表着统一的传输数据类uvm_tlm_generic_payload,而P代表着在nonblocking传输方式中用来做状态同步的类型。


在定义TLM2.0的过程中,仍然有initiator和target的概念,也有port、export以及imp的端口类型。正如上一节课谈到的,对于port类型,它是用来发起请求用来调用target一端的接口方法,而export用来传导这一要求,最后由imp端口的例化组件来实现数据传输的方法。


为了区别于TLM1.0对于端口类型的称谓,在UVM中实现的TLM2.0端口类型称之为socket。它们是由port、export和imp组合而成的。一个socket首先是双向的传输的,这一点类似于上一节中谈到的双向传输。例如在TLM1.0中的双向传输中transport可以用来做单次完成的双向传输,master和slave端口用来完成多次单向的传输。而socket则按照blocking和nonblocking的传输方式,和initiator和target的发起区别一共可以分为下面的端口类型:

  • uvm_tlm_b_initiator_socket

  • uvm_tlm_b_target_socket

  • uvm_tlm_nb_initiator_socket

  • uvm_tlm_nb_target_socket

  • uvm_tlm_b_passthrough_initiator_socket

  • uvm_tlm_b_passthrough_target_socket

  • uvm_tlm_nb_passthrough_initiator_socket

  • uvm_tlm_nb_passthrough_target_socket


从下面的类的继承树来看,这些socket类型也都继承于uvm_port_base,具有同TLM1.0端口一样的基函数。而对于这些socket的内部,它们则是通过例化port、export以及imp最终来实现数据双向传输的。


TLM2.0的port、export和imp类型不同于TLM1.0的部分,首先这些相关的端口类型是新引入的类,例如uvm_tlm_b_transport_port、uvm_tlm_b_transport_export和uvm_tlm_b_transport_imp。这里没有改变的概念是不同端口类型之间的连接关系,改变的只是新的端口类型名所匹配的方法不再是put()、get()、peek()而是变为了b_transport()、nb_transport_fw()和nb_transport_bw()。这些socket通过内置例化这些端口的例化,最终可以实现数据的双向传输。上面8中socket可以按照传输方式和发起方向来区分:



这里IS-A代表这继承关系,而HAS-A表示对象之间的关联。fw表示request的发送通道,bw表示response的发送通道。


传送数据

在TLM1.0中传送的数据类型是由用户自己定义的,这就对组件之间的数据传输做出了更多的限制。例如,如果端口的传输数据类型不同,则端口无法连接,同时针对不同的传送数据类型,相应的传送方法也要做出调整,因此这种方式实际上不利于组件之间的快速连接和整个平台的搭建。TLM2.0中对于传送的数据也提出了一致化的要求,这里统一的数据类由uvm_tlm_generic_payload表示,即上面的传输方法中使用的数据类都应该为uvm_tlm_generic_payload。为了保持TLM2.0端口部分的良好连接性,我们并不建议再在uvm_tlm_generic_payload的基础上做出更多的扩展,实际上这个类本身就可以容纳更多的扩展数据域部分。接下来,我们逐个分析这个类种的各个域的功能,在分析前读者需要知道的是,TLM2.0一开始发布的背景就是为了解决总线级别的抽象问题,所以它的统一数据包格式也是按照总线数据的内容来定义的。

  • bit [63:0] m_address:数据读写的地址。

  • uvm_tlm_command_e m_command:数据的读写命令。

  • byte unsigned data[]:写入的数据或者读出的数据,由byte unsigned的类型构成动态数组,这是按照总线传输的最小粒度进行划分,便于target一侧进行数据的整合。

  • int unsigned length:data数组的长度,该数值应该与data数组的实际容量保持一致。

  • uvm_tlm_response_status_e  m_response_status:由target返回的状态值,表示数据传输是否完成和有效。

  • byte unsigned m_byte_enable[]:用来标记写入数据的有效性,标记哪个byte应该写入。

  • int unsigned m_byte_enable_length:该数值应该等于m_byte_enable数组的容量值。

  • m_stream_width:用来表示连续传输时的数据传输长度。

  • uvm_tlm_extension_base m_extensions [uvm_tlm_extension_base]:如果一些数据域不在上面的部分,那么则可以在这个数据延伸域中添加。


从上面各个数据域的介绍来看,对于一般的总线传输而言,这里的包含的数据信息已经足够,那么如果该传输还包括其它的数据内容,该怎么办呢?一种办法是,将其压包作为数据成员data数组中的一部分,或者另外一种办法是创建新的uvm_tlm_extension类,将其它额外的数据成员装入到该数据延伸对象中,通过uvm_tlm_generic_payload::set_extension(uvm_tlm_extension_base ext)来添加这一部分的数据。对于一个数据类而言,拷贝、比较和打印功能是必不可少的,而该类已经提供了do_copy()、do_compare()和do_print()回调函数来满足这一要求。


时间标记

不同的时间标记间隔是SystemC可以构建不同时间精确度的重要手段。尽管SystemC原则上也可以通过自建时钟源通过时钟事件来驱动内部逻辑,但是为了提高模型的运行效率,还是将整个数据传输和处理的时间都通过标记的时间来反映出来,这就很大程度上避免了时钟依赖。在TLM2的传输中,由于可以标定延迟时间,这使得target端可以模拟延迟,并且在准确的延迟时刻来做出响应。


为了能够便于标记延迟时间,例如实数范围的延迟1.1ns(SystemVerilog继承与Verilog的时间精度方式,只能使用整数的延迟方式),UVM新建了一个时间类uvm_tlm_time。这个时间类的便捷之处在于用户可以随时设置它的时间单位(默认为1ps),并且进行时间的增减设置操作。同时,这个类的存在,也是为了解决在不同模块或包之间出现不同时间单位和精度单位的问题。可以有了这么灵活的时间类,对于target一侧要进行时间等待这些操作就容易得多了,也不会出现时间和精度单位错误的问题。


典型使用

接下来我们就利用TLM2的socket来建立一个轻量的例子,读者们可以从这个例子中体会一下与TLM1.0相比,TLM2.0传输的特点有哪些。



输出结果:



从这个例子可以看出,有了标准的传输数据包和准确的延迟时间,方便了模块之间的复用和建立更高层级的模型。尽管目前UVM组件之间的传输仍建立在TLM1.0,也不排除日后要求支持TLM2.0的传输方式。至少目前,我们已经可以看到一些成熟的商业VIP的接口已经同时支持TLM1.0的sequence item传输方式和TLM2.0的socket接口方式。从实用角度来看,TLM2.0在UVM中的实现,是为了可以同SystemC的TLM2.0接口可以无缝衔接,关于SystemC模型在UVM中的连接嵌入和使用方式,我们也会在后面关于SV/UVM同其它语言接口的实现中介绍。


下一节我们将带来本章的最后一节,关于组件之间同步的UVM方法《同步通信元件》。


谢谢你对路科验证的关注,也欢迎你分享和转发真正的技术价值,你的支持是我们保持前行的动力。


点赞

评论 (0 个评论)

facelist

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

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 253

    粉丝
  • 25

    好友
  • 33

    获赞
  • 45

    评论
  • 访问数
关闭

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

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

GMT+8, 2024-3-29 07:36 , Processed in 0.015780 second(s), 12 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部