IC验证学霸笔记4——UVM--TLM通信

TLM通信

在芯片开发流程中,有两个地方对项目的助推起到了关键作用:
系统原型&芯片验证
系统原型一般通过硬件功能描述文档模拟硬件行为, 行为要求不同于RTL模型。 系统原型提供一个准确到硬件比特级别、 按照地址段访问、 不依赖于时钟周期的模型, 该模型通常基于SystemC语言,而系统原型中各模块通过TLM可以实现宽松时间范围内的数据包传输。

芯片验证是在RTL模型初步建立后, 通过验证语言和方法学如SV/UVM来构建验证平台。该平台的特点是验证环境整体基于面向对象开发,组件之间的通信基于TLM, 而在driver与硬件接口之间需将TLM抽象事务降解到基于时钟的信号级别。 

系统原型阶段和芯片验证阶段均使用了TLM通信方式。前者是为了更快地实现硬件原型之间的数据通信,后者是为了更快地实现验证组件之间的数据通信

仿真速度是TLM对项目进度的最大贡献,同时TLM传输中的事务又可以保证足够大的信息量和准确性。

TLM并不是某一种语言产物,而是作为一种提高数据传输抽象级的标准存在。

高抽象级的数据通信,可以用来表示宽松时间跨度内的硬件通信数据,而通过降低颗粒硬件周期内的数据打包为一个大数据,非常有利于整体环境的仿真速度。

TLM的运用越来越广泛,包括emulator同硬件仿真器的协同仿真框架中,也建议使用这种方式来降低混合环境之间的通信频率,以便提高整体的运算效率。


TLM 是一种基于事务 (transaction) 的通信方式, 通常在高抽象级语言如 SystemC 或SV/UVM中作为模块之间的通信方式。TLM成功地将模块内的计算和模块之间的通信从时间跨度方面剥离开了。 在抽象语言建模体系中, 各模块通过一系列并行的进程实现, 同时利用通信和计算模拟出正确的行为。

要提高系统模型的仿真性能, 需要考虑两个方面: 建模自身的运算优化, 模型之间的通信优化。前者依靠开发者的经验和性能分析工具来逐步优化模型,后者则可以通过将通信频率降低、 内容体积增大的方式减少由不同进程之间同步带来的资源损耗TLM 正是从通信优化角度提出的一种抽象通信方式。

TLM通信需要两个通信的对象,这两个对象分别称为initiator和 target。区分它们的方法在于,谁先发起通信请求,谁就属于initiator,而谁作为发起通信的响应方,谁就属于target。 

通信发起方并不代表了transaction的流向起点,即不一定数据是从initiator流向target, 也可能是从target流向了initiator,因此按照transaction的流向,我们又可以将两个对象分为producer和consumer。区分它们的方法是,数据从哪里产生,它就属于producer, 而数据流向了哪里,它就属于consumer。

initiator与target的关系同producer与consumer的关系不是固定的。
有了两个参与通信的对象之后,用户需要将TLM通信方法在target端中实现,以便于initiator将来作为发起方可以调用target的通信方法,实现数据传输。

在target实现了必要的通信方法之后,最后一步我们需要将两个对象进行连接,这需要在两个对象中创建TLM端口,继而在更高层次中将这两个对 象进行连接。


因此我们可以将 TLM 通信步骤分为:
1  分辨出 initiator和target, producer和consumer。
2   在 target 中实现 TLM 通信方法。
3   在两个对象中创建 TLM 端口。
4  在更高层次中将两个对象的端口进行连接。
 

从数据流向来看, 传输方向可以分为单向(unidirection)和双向 (bidirection):
 •    单向传输:由initiator发起request transactio;
 •    双向传输:由initiator发起request transaction, 传送至target; 而target在消化 了request transaction后,会发起response transaction, 继而返回给initiator。

端口的按照类型可以划分为三种:
•    port: 经常作为initiator的发起端, initiator凭借port才可以访问target的TLM通信方法。
•    export: 作为initiator和target中间层次的端口。
•    imp: 只能作为target接收request的未端, 它无法作为中间层次的端口, 所以imp的连接无法再次延伸。

如果将传输方向和端口类型加以组合,综合下来, TLM 端口一共分为 6 类:
•     uvm_UNDIR_port #(trans_t)     uvm_单双向_端口类型 # (类型参数)
•     uvm_UNDIR_export # (trans_t)
•     uvm_UNDIR_imp # (trans_t,imp_parent_t)
•     uvm_BIDIR_port # (req_trans_t, rsp_trans_t)
•     uvm_BIDIR_export #(req_trans_t, rsp_trans_t)
•     uvm_BIDIR_imp # (req_trans_t, rsp_trans_t, imp_parent_t)

就单向端口而言,声明 port 和 export 作为 request 发起方,需要指定 transaction 类型参数, 而声明 imp 作为 request 接收方, 不但需要指定 transaction 类型参数, 还需要指定它所在的 component 类型。 就声明双向端口而言, 指定参数需要考虑双向传输的因素, 将传输类型 transaction 拆分为 request transaction 类型和 response transaction 类型。

TLM 端口连接的一般做法:

•    在 initiator 端例化 port, 在中间层次例化 export, 在 target 端例化 imp;

•    多个 port 可以连接到同一个 export或imp; 但单个 port或export 无法连接多个imp 。这可以理解为多个initiator 可以对同一个 target 发起 request, 但是同一个initiator 无法连接多个target。

•    port 应为 request 起点, imp 应为 request 终点, 而中间可以穿越多个层次。 基于单元组件的自闭性考虑, 笔者建议在穿越的中间层次声明 export, 继而通过层层连接实现数据通路。

•    port 可以连接 port 、 export 或 imp: export 可以连接 export 或 imp; imp 只能作为数据传送的终点, 无法扩展连接。

从示例中可以得出关于建立TLM通信的常规步骤:

•    定义TLM传输中的数据类型,上面分别定义了request类和response 类。
•    分别在各个层次的component中声明和创建TLM端口对象。
•    通过connect()函数完成端口之间的连接。
•    在imp端口类中要实现需要提供给initiator的可调用方法。例如,在 comp2中由于有一个uvm_nonblocking_put_imp #(request, comp2) nbp_imp, 因此需要实现两个方法try_pu( )和can_put();而comp4中有一个uvm blocking_get_imp #(request, comp4) bg_imp, 则需要实现对应的方法get()。
•    需要注意的是,必须在imp端口类中实现对应方法,否则端口即使连接也无法实现数据传输。

注:优秀验证学员随堂笔记,已经征求到学生的同意,会持续给牛友们分享!
大家看完记得 一键三连!多多支持

#深度学习##做项目##芯片IC验证工程师##你为什么选择硬件行业##你的秋招进展怎么样了#
全部评论
还的是学霸呀
点赞 回复 分享
发布于 2022-09-29 16:36 河南

相关推荐

待现的未见之事:起码第一句要把自己的优势说出来吧。比如什么xx本27届学生,随时到岗....
点赞 评论 收藏
分享
吴offer选手:HR:我KPI到手了就行,合不合适关我什么事
点赞 评论 收藏
分享
评论
2
3
分享

创作者周榜

更多
牛客网
牛客企业服务