前 言
本文主要给大家介绍SV宏,谈到SV宏大家应该不会感到陌生,因为大家在做前端设计或验证的时候会用到`define定义宏,进行条件编译,或者使用宏来定义参数等,做前端验证的工程师会使用`define来定义一些信号路径等。这些SV宏的用法都是比较常规的用法,很少有验证工程师使用SV宏来处理一些其他的事情。猜其原因主要是大家对SV宏的语法及应用场景不了解,很少有相关资料进行说明,即使作为验证验证工程师人手必备的绿皮书也只是在数据结构章节简略提到了使用`define定义参数。验证工程师在搭建UVM验证平台时经常会使用SV宏,比如`uvm_info、`uvm_error、`uvm_fatal, 亦或者是`uvm_do等, 但是大多数工程师只是知道如何调用这些宏,并不知道这些宏的内部结构。这些宏都是UVM源码中使用时SV宏进行定义的。SV宏作为Systemverilog中最强大的功能之一,如果验证工程师可以透彻的了解,正确地应用于验证平台中,可以节省大量的时间,提高代码的可读性和高效性。
那么为什么建议大家要学会和正确使用SV宏呢?
对于任何设计验证项目,遵循最佳的编码实践可以让你的队友的工作更加轻松。另一方面,糟糕的编码风格会在代码重复使用或当代码移交给另一个所有者以在未来进行加强时导致很多的问题。有时,这会导致代码中的大量返工和补丁,并使代码在项目的后期或需要重复使用的未来项目中的维护变得非常困难。
通常,在进行设计验证项目时,需要将较大的代码段分成较小的块,以使代码更易于阅读和调试(以及出于可重用性的目的)。此类较小的代码段可在设计验证环境中的不同位置用于多个组件、模块等。
- 验证工程师提问:我们为什么不能使用函数或者任务达到同样的目的呢?
任务和函数可用于将大型、复杂的代码分解为更小、更简单的代码段,易于阅读和理解。函数和任务主要用于在验证环境中的多个位置执行相同功能,但是它们的用法仅限于定义它们的模块或类访问边界。对于在不同且完全隔离的模块中常见且经常使用的某些代码,由于其访问边界限制,该函数/任务无法直接重用。
举一个简单的例子,如果任务/函数具有用于两个不同monitor和两个不同接口的相同代码,则验证工程师通常会在两个monitor中添加重复的代码。在许多其他情况下,我们会看到代码重复。"SV宏"是解决此类重复的众多解决方案之一。
如果在SV环境中正确使用宏,它将非常有效,并且可以帮助节省大量时间。为了可以让大家透彻了解SV宏,本文重点讨论了SV宏及语法,并提供一些示例来说明在何处使用它可以节省验证时间。
什么是宏(macro)?

“宏”是指一行或几行文本代码的替换,即使用`define编译器指令创建的代码段。一旦宏定义了,可以在需要时在编译单元范围内的任何位置使用它。宏本质上有三部分组成,即名称,一些文本和可选参数。可以通过(`)字符后跟宏名称来调用它。一个宏可以使用参数定义。参数对于自定义要广泛使用的宏很有用,例如一个函数/任务。此类宏参数可以使用默认值定义,这样如果设计验证工程师不传递任何特定值,则宏将替换为默认值。
宏定义
单行宏: