简化的UVM实际上是UVM的一个子集,但是它为学习UVM提供了一个好的起点:UVM的其它功能会随着用户自信心的提高逐步被引入。
本文介绍了一系列特定的编码指南,有助于给新用户提供最佳实践的明确方向;还介绍了一个能自动生成代码的工具,可以为新项目生成第一层的UVM代码库,组成UVM基本结构。提供了以下具体好处:
- 简化的UVM可以帮助个人和团队更快开始UVM实践,通过实践巩固学到的知识,避免最常见的陷阱。
- 简化的UVM可以帮助个人和团队更早用UVM投入项目开发,在工业项目的实际使用中,我们发现使用
代码生成器可以在项目开始阶段减少大约6周代码开发工作。
- 简化的UVM可以使得团队使用UVM的方式更加一致,从而使得项目继承和维护更加容易。
- 简化的UVM有助于规划和执行UVM项目变得更加可预测,有利于项目按计划进行。
编码指南
1. 编码格式
简化的UVM编码指南从定义编码格式开始,比如最常见的用户定义的UVM类,包括显而易见的诸如声明的顺序,特定的命名约定,要使用的宏,以及要覆盖的方法等。
一个非常具体但非常任意的选择的例子是关于命名约定。 我们建议使用特定的前缀和后缀,在命名类用(m_),端口时使用(_port),虚拟接口使用(_vif)等。
作为任意选择的存有争议的一个例子,比如是否允许使用字段宏,我们的建议是:
(a) 当不使用字段宏(我们推荐)时,在类的第一行使用这两个宏(`uvm_component_utils 或者`uvm_object_utils )之一注册类。
(b)如果使用字段宏(我们不推荐)时,注册类和字段可以紧接在声明任何成员变量之后使用这两个宏(`uvm_component_utils_begin 或 `uvm_object_utils_begin)之一来实现。
作为任意选择的另一个例子,当想要在执行序列的主体任务之前或之后执行代码时,我们建议重写回调的pre_start和post_start,而不是用 pre_body 和 post_body。
2.一般准则
我们给出详细的一般准则,包括以下良好做法:
- 将test从env里分离出来
- 开发验证组件和test时就要考虑以后复用
- 使用工厂和配置数据库
- 使用事务级端口和输出
- 使用虚拟接口
- 使用run-time phases
- 在多个平行代理时,使用虚拟序列和记分板
- 在用户定义报告里合理使用消息ID和详细信息
- 使用寄存器层
- 建议功能覆盖
- 建议包装数据和结构化文件以供重复使用
代码自动生成
代码生成器本身是用Perl编写的,下载Apache 2.0许可证,可以免费使用。 它生成SystemVerilog代码,符合我们的编码指南,但因为它是开源,如果需要,可以根据具体项目情况修改生成代码。
代码生成器创建所有必需的样板代码来扩展UVM类,如drivers,monitors and agents,,定制与应用程序特定的信息,如transaction字段和TLM端口名称。应用程序特定信息从一个简单的模板进入Perl脚本。用户也可以插入它们自己的应用程序特定的代码,Perl脚本将优先使用用户定义的这些特定代码。
代码生成器为任何给定的DUT interface创建以下文件集,其中<name>是指定的前缀:
这个流程具有统一的文件结构和统一的方法组织各种元素(代理,接口,包,序列...),有助于保持整个团队或公司的一致性。
用户提供给代码生成器一个安装文件,它定义了每个DUT接口的内容,以及每个 sequence item,通过这个文件,代码生成器为每个DUT 接口创建Sequence item,Sequencer,Driver,Monitor等类,在顶层,代码生成器会生成Top-level module, Env和Test。
1.代码生成的实践经验
对于典型项目,代码生成可能如下步骤进行:
- 识别顶层DUT,枚举其所有的功能接口
- 创建安装文件,文件命名每个DUT Interface对应的引脚和事务变量
- 生成完整环境的代码。
- 仿真整个环境。
- 开始逐个实现驱动。
- 通过添加新序列并依次仿真每个driver测试环境,而许多部分环境仍然缺失。 这有助于演示正在取得的进展。
- 插入 monitors, subscribers, scoreboards,并进一步添加序列和测试。
- 随着测试越来越复杂,添加更多的数据成员到序列项目并且将方法细化。
结论
我们见证了用户极大的热情,是对于提供一套关于实践UVM代码的编码指南的热情。UVM编码指南和代码生成器能否被广泛采用将有待观察,但无论如何,我们仍然相信有必要这样做一套超越UVM类库本身的指南随附文档。