在软件工程的早期,人们与项目的复杂性增长和大型开发团队的管理挑战进行了艰巨的斗争,面向对象编程(OOP)为解决这些问题带来了革命性的解决方案。
随着代码重用性和验证IP在硬件验证中变得越来越普遍,也越来越适用OOP概念。
如何设计大型程序呢?OOP建议使用“divide and conquer(分而治之)”。
程序是一组相关的对象进行交互。例如模拟交通的程序将涉及汽车(cars),驾驶员(drivers)和交通信号灯(traffic lights),我们应该专注于设计单个模块(汽车、驾驶员和交通信号灯)的操作而不是直接设计整个复杂的交通系统程序。对于测试平台或验证项目也是一样,我们应该关注完成特定功能的最终构成测试平台的组件。
人类使用抽象来概括世界。汽车的抽象概念是:四个轮子,一个引擎,至少两个门,方向盘等。这种抽象能力使我们能够组织数据并实现高效的沟通。例如你可以说“我昨天开车去上班”,听众会理解的而无需说明你开的是特斯拉还启动了辅助驾驶。这些细节对于表达意图是没有必要的。
面向对象的编程使我们可以在软件设计上做同样的事情。可以定义一个通用类,并使用继承创建该抽象类的特定实例。
class(类)定义了对象的抽象特征(属性,attributes)和行为(方法,methods)。这是一个用于创建一个或多个相同类型对象的蓝图(blueprint)。例如有一个汽车类定义了所有汽车对象可以包含的东西,然后在该类基础上定义具有某种特殊属性(品牌、颜色和引擎等)的特殊汽车,例如银色的保时捷跑车。
使用继承可以允许具有足够相似接口的对象共享代码。父类仅用于实现重用和抽象,声明为virtual class,永远不要实例化父类。
对象保存运行时的数据并用作构建程序,程序实例化对象并触发对象之间的互动。
代码语言:javascript复制class car; // class definition
task void run(); // public interface task void open();
endclass: car
module top;
car my_car = new; // object of instance creation
my_car.run();
endmodule: top
SystemVerilog类的动态特性与Verilog模块(module)实例不同。模块实例是在Verilog进行elaboration时创建的并且存在于整个仿真过程,对象可以根据要求在运行时创建。在功能验证中,测试平台的构建过程是动态的,这使其更加灵活。
代码语言:javascript复制endclass: car