SystemVerilog的UVM学习(二)
在 SystemVerilog 和 UVM 中,fpu_env、fpu_init_seq 和 fpu_add_seq 是 自定义类,它们并不是直接继承自 UVM 的标准类,而是由你或者你的团队根据验证需求重新定义的类。它们是 验证环境的一部分,负责处理特定的任务。
1. 它们是自定义类,还是继承的?
这些类(如 fpu_env、fpu_init_seq 和 fpu_add_seq)通常是 自定义类,并且它们可能会继承自 UVM 的基类(如 uvm_component、uvm_sequence 等)来实现一些标准功能。也就是说,它们是根据需要创建的类,并且可能会选择继承 UVM 标准类,以便利用 UVM 提供的功能和设计模式。
2. fpu_env 类的作用:
fpu_env 类代表一个 FPU 加法器的测试环境。它可以继承自 uvm_env 或 uvm_component,用于组织和管理与 FPU 相关的所有验证组件,如 驱动器、监视器、代理 等。
fpu_env可能继承自uvm_env,后者是 UVM 中用于封装环境相关组件的基类。
示例:
class fpu_env extends uvm_env;
// 子组件:例如 驱动器(driver)、监视器(monitor)等
fpu_driver driver;
fpu_monitor monitor;
// 构造函数
function new(string name = "fpu_env", uvm_component parent = null);
super.new(name, parent);
endfunction
// build_phase 阶段:实例化子组件
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
driver = fpu_driver::type_id::create("driver", this);
monitor = fpu_monitor::type_id::create("monitor", this);
endfunction
endclass
3. fpu_init_seq 类的作用:
fpu_init_seq 类代表一个 初始化序列,它负责为 FPU 加法器配置初始状态(如寄存器设置、输入初始化等)。它通常会继承自 uvm_sequence,这是 UVM 中用于描述 序列 的基类,定义了如何执行一系列的验证操作。
示例:
class fpu_init_seq extends uvm_sequence #(fpu_transaction);
// 构造函数
function new(string name = "fpu_init_seq");
super.new(name);
endfunction
// body 阶段:执行初始化步骤
virtual task body();
// 模拟初始化步骤,例如设置 FPU 的初始值
start_item(req);
req.opcode = `FPU_INIT;
finish_item(req);
endtask
endclass
4. fpu_add_seq 类的作用:
fpu_add_seq 类代表一个 加法操作序列,它描述了如何执行 FPU 加法器的 加法操作。它可能会继承自 uvm_sequence,用于生成一组输入数据并验证结果。
示例:
class fpu_add_seq extends uvm_sequence #(fpu_transaction);
// 构造函数
function new(string name = "fpu_add_seq");
super.new(name);
endfunction
// body 阶段:执行加法操作的步骤
virtual task body();
// 模拟加法操作步骤,例如提供两个输入并检查加法结果
start_item(req);
req.opcode = `FPU_ADD;
finish_item(req);
endtask
endclass
5. 类的组织和职责
fpu_env类:代表整个 FPU 加法器的测试环境,负责 环境的搭建,比如创建驱动器、监视器等组件。fpu_init_seq类:负责执行 FPU 初始化操作,设置初始状态。fpu_add_seq类:执行 FPU 加法操作,包括加法输入、结果验证等。
这些类是根据 测试需求 和 验证环境 的设计目标 自己定义的,而不是 UVM 中的标准类。它们可能会继承 UVM 的标准类(如 uvm_env、uvm_sequence 等),以便重用 UVM 提供的功能,比如 工厂机制、序列控制、测试阶段管理 等。
6. 如何创建和使用这些类:
这些类通过 new 构造函数 创建对象,并在验证环境的 不同阶段(如 build_phase、run_phase 等)中被使用和调度。
- 在
fpu_add_test类中,fpu_env、fpu_init_seq和fpu_add_seq是作为 子组件 被实例化的。fpu_add_test会通过build_phase和run_phase来管理它们,并确保测试按照预期执行。
7. 总结:
fpu_env、fpu_init_seq和fpu_add_seq是 自定义类,它们的设计是为了完成特定的验证任务,如 环境搭建、初始化、加法操作。- 这些类可能会继承自 UVM 的标准类(如
uvm_component、uvm_sequence),从而利用 UVM 提供的 验证功能 和 设计模式。 - 通过组合这些类,你可以创建一个 模块化、可扩展的验证环境,用于测试 FPU 加法器 等功能。
在 UVM 中,fpu_add_test 类继承自 uvm_test 类的关系是通过 extends 关键字 明确指定的。在你提供的代码中,fpu_add_test 类通过 extends uvm_test 表示它继承自 uvm_test。
代码中体现的地方:
class fpu_add_test extends uvm_test;
1. extends uvm_test
extends关键字表示 继承,也就是fpu_add_test类是从uvm_test类派生出来的。- 通过继承,
fpu_add_test可以使用uvm_test中定义的所有功能和方法,此外,fpu_add_test还可以 重写 这些方法或添加新的功能来实现 FPU 加法器测试。
2. uvm_test 是 UVM 中的一个基类
-
uvm_test是 UVM 框架中的一个基类,表示一个 验证用例(test case)。 -
uvm_test类继承自uvm_component,它提供了一个标准化的 测试流程管理,包括:- 初始化阶段:设置验证环境。
- 执行阶段:执行验证步骤(如运行验证序列)。
- 清理阶段:清理测试后操作。
3. fpu_add_test 的作用
fpu_add_test是一个具体的 测试用例 类,它继承自uvm_test,并在此基础上添加了 FPU 加法器 的验证逻辑。- 通过继承
uvm_test,fpu_add_test可以利用 UVM 提供的结构化流程,例如 阶段(phases)(如build_phase、run_phase等)和 组件管理(如创建环境组件、序列等)。
4. 代码结构说明:
class fpu_add_test extends uvm_test;
`uvm_component_utils(fpu_add_test) // 使用宏注册到UVM工厂中
fpu_env env; // FPU 环境
fpu_init_seq init_seq; // 初始化序列
fpu_add_seq add_seq; // 加法序列
function new(string name = "fpu_add_test", uvm_component parent = null);
super.new(name, parent); // 调用父类构造函数
`uvm_info("fpu_add_test", "Inside constructor of fpu_add_test", UVM_HIGH)
endfunction
endclass
5. uvm_test 的继承关系:
fpu_add_test通过extends uvm_test显式继承了uvm_test类,这意味着fpu_add_test是 UVM 测试用例,并具备uvm_test类提供的所有功能。fpu_add_test可以在其构造函数、build_phase、run_phase等方法中实现特定的测试步骤。
6. uvm_test 的功能:
uvm_test是一个基类,通常在 UVM 仿真框架 中用于创建具体的验证测试。- 你可以在
fpu_add_test中通过重写build_phase、run_phase等方法来执行你的验证工作。
7. 总结:
fpu_add_test继承自uvm_test,通过extends关键字 显式指定。fpu_add_test可以使用uvm_test类中的方法和功能,并且可以根据实际需要对这些方法进行 重写。- 通过继承
uvm_test,fpu_add_test成为一个完整的 UVM 测试用例,具备标准的测试功能和验证流程。
function new 是 SystemVerilog 中用于类的构造函数(constructor)的定义,它在创建类的实例时自动调用,用于初始化类的属性、资源等。通过构造函数,类的对象可以在实例化时获得初始的状态或设置。
1. 构造函数的作用:
构造函数 new 在 UVM 中,通常用于初始化 测试类(如 fpu_add_test) 的各个组件,确保在测试执行前为这些组件分配必要的资源或状态。它类似于其他编程语言中的构造函数,目的是 初始化类的对象,使其具备正确的初始值和环境。
2. function new 的含义:
function new(string name = "fpu_add_test", uvm_component parent = null);
super.new(name, parent); // 调用父类构造函数
`uvm_info("fpu_add_test", "Inside constructor of fpu_add_test", UVM_HIGH)
endfunction
解释:
function new()是类fpu_add_test的 构造函数,当你创建fpu_add_test的实例时,new函数会自动被调用。string name = "fpu_add_test":这是构造函数的第一个参数,name,表示fpu_add_test类的名称。它有一个默认值"fpu_add_test",如果实例化时没有传入name参数,则使用默认值。uvm_component parent = null:这是构造函数的第二个参数,parent,表示当前类的父组件。在 UVM 中,组件通常有层次结构(父组件和子组件),如果没有显式指定父组件,则默认设置为null。
3. super.new(name, parent):调用父类的构造函数
super.new(name, parent);
super.new(name, parent):调用父类uvm_test的构造函数。这里的super关键字表示调用父类的构造函数,确保继承自uvm_test的功能得到正确初始化。name和parent参数会被传递给父类的构造函数。
在 fpu_add_test 中,通过调用 super.new(name, parent),确保 fpu_add_test 在继承 uvm_test 的同时,能够正确初始化其父类中的属性和功能。
4. uvm_info:输出调试信息
`uvm_info("fpu_add_test", "Inside constructor of fpu_add_test", UVM_HIGH)
-
uvm_info是一个 UVM 宏,用于在仿真中输出调试信息。"fpu_add_test":这是信息的标识符(Tag),帮助区分不同的消息来源。"Inside constructor of fpu_add_test":消息的内容,表示当前正处于fpu_add_test类的构造函数中。UVM_HIGH:是消息的优先级,UVM_HIGH表示高优先级的调试信息,适用于开发阶段,帮助追踪程序的执行。
5. 形象解释 new 函数的功能:
类似现实生活中的 构造过程:
可以将 new 函数类比为你在 工厂里生产一台机器 的过程:
-
当你从工厂拿到机器时,机器已经完成了所有的基本初始化工作,例如电池安装、设置默认参数等。
-
new函数 就是执行这类初始化工作的工具,确保你获得的对象(例如fpu_add_test类的实例)是 准备好的,可以立即开始使用。- 它设置了 名字(
name)。 - 它确保机器(
fpu_add_test)有正确的 父组件(parent) 关系,符合设计的层次结构。 - 它还输出一条调试信息,告诉你这台机器已经准备好了。
- 它设置了 名字(
测试环境中的作用:
- 初始化组件:通过
new构造函数,fpu_add_test类会创建其成员变量,如fpu_env、fpu_init_seq、fpu_add_seq等组件,确保这些组件在测试开始前已经正确配置和初始化。 - 调试信息:通过
uvm_info输出的信息,你可以在仿真日志中看到是否成功进入了构造函数,帮助你验证测试环境的初始化是否成功。
6. 总结:
function new是fpu_add_test类的 构造函数,它在实例化时被自动调用,负责 初始化对象 并为其设置默认值或执行配置。- 通过
super.new(name, parent)调用父类uvm_test的构造函数,确保继承的功能能够正确初始化。 uvm_info输出了一条调试信息,帮助你确认构造函数是否执行。
简而言之,new 构造函数是一个 初始化过程,确保你创建的 fpu_add_test 对象已经具备运行所需的环境和配置,并且能够在仿真过程中正常执行。
env = fpu_env::type_id::create("env", this); 这一行代码的作用和背后的概念。
背景概念:
在 UVM(Universal Verification Methodology)中,我们通常使用 工厂模式 来创建 组件。通过 工厂方法,你可以动态创建不同类型的 验证组件,并将它们组织成层次化的结构(父子组件关系)。这一点非常适合构建复杂的验证环境,因为它允许你 动态创建 组件,并且通过父子关系来管理它们。
代码分析:
env = fpu_env::type_id::create("env", this);
这一行代码的目的是使用 UVM 工厂方法 来创建一个类型为 fpu_env 的组件,并将该组件命名为 env。创建的组件会作为 fpu_add_test 的子组件。
我们来分解这段代码:
-
fpu_env::type_id::create("env", this):-
fpu_env是一个类,表示 FPU 加法器的测试环境。它可能包含与 FPU 加法器 测试相关的多个组件(如驱动器、监视器、代理等)。 -
type_id是 UVM 中的一个工厂方法,用来创建 指定类型的组件。type_id是 UVM 中的 类型标识符,它会自动管理组件类型,并支持动态创建实例。 -
create("env", this):"env":这是创建的 组件实例的名称,也就是该fpu_env实例的名字。this:表示 当前组件(fpu_add_test) 的实例。this会传递给fpu_env,让它知道它的父组件是谁。UVM 会根据 父子组件关系,将fpu_add_test作为fpu_env的 父组件。
-
-
env =:- 这部分表示创建的
fpu_env实例会被赋值给env,即fpu_add_test中的env变量。env是一个类型为fpu_env的对象,表示当前测试用例中的 FPU 环境。
- 这部分表示创建的
为什么要使用 type_id::create ?
在 UVM 中,工厂模式 被广泛使用。type_id::create 是 UVM 的工厂方法,允许你在仿真过程中动态创建 不同类型的组件。使用工厂模式的好处包括:
- 类型安全:
type_id确保你创建的组件类型是正确的。 - 动态创建:你不需要在设计时硬编码组件类型,而是可以在运行时根据需要动态创建不同的组件。
- 统一管理:工厂模式帮助管理组件的实例化、创建、销毁等过程,简化了复杂验证环境的管理。
具体例子:
在这段代码中,fpu_add_test 作为 测试用例,它需要一个 FPU 加法器的测试环境(即 fpu_env)。通过 type_id::create,我们可以动态创建 fpu_env 实例,并将其命名为 env。env 将会成为 fpu_add_test 的子组件,并通过 this 参数建立父子关系。
更形象的类比:
假设你在做一个 FPU 加法器的验证,你需要为测试创建一些 组件,例如:
fpu_env:是你的 验证环境,它包含了 FPU 的驱动器、监视器等组件。通过fpu_env::type_id::create创建它。fpu_add_test:是整个测试用例,它负责协调和管理fpu_env,控制测试流程。
类比:想象你有一个 工作场所(fpu_add_test),里面有一个 工作台(fpu_env)。通过 type_id::create,你给工作台命名为 env,并把它放入工作场所。fpu_add_test 负责指挥 工作场所,而 工作台(fpu_env) 负责执行具体的 工作(即测试)。
总结:
env = fpu_env::type_id::create("env", this);通过 UVM 工厂方法type_id::create创建了一个fpu_env类型的 测试环境 实例,并将其命名为env。this参数将当前fpu_add_test作为父组件传递给fpu_env,使得fpu_env成为fpu_add_test的子组件。- 通过工厂模式,UVM 提供了动态创建和管理组件的能力,这样你可以更灵活地构建和配置测试环境。
这段代码定义了 run_phase 任务,它是 fpu_add_test 测试用例中的一个重要阶段。run_phase 是 UVM 测试中的一个阶段,用于执行实际的测试步骤。下面我们逐步分析这段代码的功能。
1. task run_phase(uvm_phase phase);
task run_phase(uvm_phase phase);
run_phase是 UVM 测试的一个标准阶段函数。UVM 中的每个测试用例都会有多个阶段,如build_phase、run_phase、end_phase等。run_phase通常用于执行 测试的主要操作,例如启动测试序列、运行仿真等。uvm_phase phase:是输入参数,表示当前的测试阶段。uvm_phase是 UVM 中的一个类,表示不同的测试阶段(如build、connect、run等)。在仿真过程中,UVM 会自动管理这些阶段的执行,并调用相应的函数。
2. super.run_phase(phase);
super.run_phase(phase);
super.run_phase(phase):调用 父类(uvm_test) 的run_phase方法。- 通过调用
super.run_phase(phase),fpu_add_test类继承自uvm_test的run_phase方法。父类的run_phase方法通常包含了 标准的测试流程控制,例如管理阶段的切换和测试的一些基础操作。
3. uvm_info:输出调试信息
`uvm_info("fpu_add_test", "Inside run phase", UVM_HIGH)
-
uvm_info是 UVM 宏,用于输出调试信息。它会在仿真日志中输出一条消息。"fpu_add_test":消息的标识符(Tag),帮助你区分不同来源的消息。"Inside run phase":消息内容,表示当前正在执行fpu_add_test类的run_phase阶段。UVM_HIGH:消息的优先级,UVM_HIGH表示高优先级的调试信息,适用于开发过程中,帮助追踪测试的执行进度。
4. phase.raise_objection(this);
phase.raise_objection(this);
-
phase.raise_objection(this):在run_phase阶段开始时,调用raise_objection来通知 UVM 测试尚未完成,它应该等待所有阶段的操作完成。this:表示当前的fpu_add_test对象,表示该对象正在请求 “阻止” 阶段的结束,直到所有测试步骤都完成。- 阶段对象
raise_objection用来告知 UVM 系统 当前阶段的操作还未完成,UVM 不会结束该阶段,直到drop_objection被调用。
5. #10ns;
#10ns;
#10ns是 延时语句,表示仿真中 暂停 10 纳秒。它通常用于模拟时间延迟,确保测试中的时序正确。- 这里的延时可能是为了给 FPU 环境一些时间准备好,或者模拟一些操作的延迟。
6. repeat(1) 和 init_seq.start(env.agent.seqr);
repeat(1) begin
init_seq = fpu_init_seq::type_id::create("init_seq");
init_seq.start(env.agent.seqr);
end
repeat(1):表示执行 1 次。这里的repeat(1)看似多余,实际上只会执行一次。init_seq = fpu_init_seq::type_id::create("init_seq");:通过 工厂方法 创建一个名为init_seq的 初始化序列(fpu_init_seq类型)。type_id::create是 UVM 工厂方法,用于动态创建fpu_init_seq的实例。init_seq.start(env.agent.seqr);:调用init_seq的start方法,并将env.agent.seqr传递给它。env.agent.seqr是 FPU 环境中代理的序列生成器(sequence generator),用于启动和执行序列。start方法会开始执行初始化序列。
7. repeat(\TESTS)和add_seq.start(env.agent.seqr);`
repeat(`TESTS) begin
#1ns;
add_seq = fpu_add_seq::type_id::create("add_seq");
add_seq.start(env.agent.seqr);
end
repeat(\TESTS)**:TESTS是一个宏,表示执行 **TESTS** 次。在实际执行时,TESTS会被替换为宏定义的值(比如100)。这里的代码表示会 **执行TESTS` 次加法操作。#1ns:表示每次执行时都会 暂停 1 纳秒,模拟每个操作的时序延迟。add_seq = fpu_add_seq::type_id::create("add_seq");:创建一个 加法操作序列(fpu_add_seq类型),名为add_seq。add_seq.start(env.agent.seqr);:启动加法序列,并将env.agent.seqr传递给它,表示 执行加法操作。
8. wait(env.scb.test_cnt == \TESTS);`
wait(env.scb.test_cnt == `TESTS);
wait是一个 等待语句,表示等待条件env.scb.test_cnt == \TESTS` 成立。env.scb.test_cnt是 FPU 环境中的计数器,表示已经执行的加法操作次数。这里,wait语句会等待加法操作次数达到TESTS(宏定义的次数)后才继续执行。
9. phase.drop_objection(this);
phase.drop_objection(this);
-
phase.drop_objection(this):在run_phase完成时,调用drop_objection来通知 UVM 当前测试阶段已经完成。- 之前,调用了
raise_objection来阻止阶段结束,直到测试完成。现在,通过drop_objection告诉 UVM 该阶段可以结束。
- 之前,调用了
总结:
-
run_phase是 UVM 测试 中的一个阶段函数,负责执行测试用例中的 主要验证步骤。 -
代码的功能:
- 调用父类的
run_phase方法,执行基础操作。 - 输出调试信息,表示进入
run_phase阶段。 - 阻止阶段结束,直到测试操作完成。
- 执行 初始化序列(
init_seq)和 加法操作序列(add_seq),重复执行加法操作TESTS次。 - 等待 加法操作次数达到预期值。
- 最后,结束阶段,允许
run_phase阶段完成。
- 调用父类的
通过这种方式,run_phase 使得 FPU 加法器 的测试过程得以系统化,逐步执行并验证加法操作,直到所有加法操作完成。
工厂模式(Factory Pattern) 是一种 创建对象的设计模式,它将 对象的实例化过程 从类的内部提取出来,交由专门的 工厂方法 或 工厂类 来负责。这种设计模式的核心目的是 解耦 对象的创建和使用,使得类与其实例化过程分离,从而提高了灵活性和可扩展性。
1. 工厂模式的基本概念:
工厂模式通过定义一个接口(或方法),由 工厂 来负责创建对象,而不是在客户端代码中直接创建实例。这样,客户端只需要依赖 工厂接口,不需要了解具体的对象实现细节。
2. 工厂模式的组成部分:
- 产品(Product):需要创建的对象。
- 工厂(Factory):负责创建 产品 的类,通常通过工厂方法来创建产品实例。
- 工厂方法(Factory Method):用于创建产品实例的方法。
3. 工厂模式的优点:
- 解耦:客户端不需要知道如何创建产品的具体实现,工厂类负责创建对象,客户端仅需依赖工厂接口。
- 扩展性好:如果你需要扩展新的产品,只需要增加新的工厂类,不需要修改现有的客户端代码。
- 可维护性:将对象的创建过程集中在工厂中,便于管理和维护。
4. 常见的工厂模式类型:
- 简单工厂模式(Simple Factory Pattern):通过一个方法创建多个不同类型的产品,但该方法通常会根据传入的参数决定创建哪个具体的产品。
- 工厂方法模式(Factory Method Pattern):由一个抽象的工厂类来定义接口,具体的子类实现该接口并返回具体的产品实例。
- 抽象工厂模式(Abstract Factory Pattern):提供一个创建产品系列的接口,每个产品系列中有多个相关的产品对象。
5. UVM 中的工厂模式:
在 UVM(Universal Verification Methodology)中,工厂模式用于 动态创建 和 管理验证组件,例如测试用例(uvm_test)、验证环境(uvm_env)等。
-
type_id::create:是 UVM 工厂方法,它是实现工厂模式的核心方法。它通过类型标识符(type_id)来创建对象。你可以用它来动态创建 UVM 组件的实例,而无需直接使用构造函数。 -
工厂方法的作用:
- 它允许 UVM 自动管理对象的生命周期(例如,创建、销毁)。
- 它让测试用例能够根据需求动态创建不同类型的组件(如环境、序列等),而不需要在代码中硬编码。
6. UVM 工厂模式示例:
假设你有一个测试用例 fpu_add_test,其中需要创建一个 fpu_env 对象,表示 FPU 加法器的测试环境。你可以使用 工厂模式 来动态创建这个对象。
// 创建 fpu_env 对象,使用 UVM 的工厂模式
fpu_env env;
env = fpu_env::type_id::create("env", this);
-
fpu_env::type_id::create:这是 UVM 的工厂方法,它创建了一个fpu_env类型的对象,并将其命名为"env",同时将当前组件(fpu_add_test)作为父组件(this)。 -
通过 工厂模式,你不需要知道
fpu_env的具体创建方式,只需要使用type_id::create来动态创建这个对象,UVM 会自动处理对象的实例化过程。
7. 更形象的类比:
假设你在一个 餐厅 点餐,餐厅菜单上有不同种类的菜肴,你不需要关心每道菜的具体做法(即具体如何创建这些菜),你只需要告诉 厨师 想要什么菜,厨师会根据菜单提供相应的菜品。
- 菜单:相当于 工厂接口,它列出了所有可以创建的对象(在 UVM 中是组件、环境等)。
- 厨师:相当于 工厂类,负责根据菜单提供具体的菜肴(即通过
type_id::create创建不同类型的对象)。 - 菜肴:相当于 具体的对象(产品),你可以根据需要点不同的菜,而不用关心它们如何做(即对象如何创建)。
8. 总结:
- 工厂模式 通过 工厂类 和 工厂方法 来封装对象的创建过程,提供一个统一的接口,允许客户端动态地创建不同类型的对象。
- 在 UVM 中,工厂模式通过
type_id::create方法实现,动态创建测试用例、环境、序列等组件,简化了组件管理和实例化过程。 - UVM 工厂模式 使得验证环境更加灵活和可扩展,便于在不同测试用例中动态地创建和管理验证组件。
在 SystemVerilog 中,有几个基础的语法和关键字用于简化代码结构和增强功能的表达。下面是对你提到的一些基础语法符号和关键字的解释:
1. :: (范围解析运算符)
在 SystemVerilog 中,:: 被称为 范围解析运算符。它用于访问类中的静态成员、调用工厂方法、引用模块实例等。它的作用类似于其他编程语言中的 命名空间 或 静态方法调用。
用途:
- 访问类的静态方法和静态成员。
- 访问模块、接口、类中的类型。
- UVM 工厂模式:通过
type_id::create调用工厂方法。
示例:
class MyClass;
static int my_value = 10;
// 静态方法
static function void print_value();
$display("Value: %0d", my_value);
endfunction
endclass
// 使用范围解析运算符访问静态成员和方法
MyClass::print_value(); // 调用静态方法
$display("Value: %0d", MyClass::my_value); // 访问静态成员
MyClass::my_value:访问MyClass类中的静态成员。MyClass::print_value():调用MyClass类中的静态方法。
2. . (成员访问运算符)
. 是 成员访问运算符,用于访问类、模块或接口的成员(如变量、方法、任务等)。在面向对象编程中,通常使用 . 来访问对象的 实例成员。
用途:
- 访问类的实例成员(变量、方法)。
- 访问模块或接口的端口和信号。
示例:
class MyClass;
int my_value;
// 构造函数
function new();
my_value = 10;
endfunction
// 方法
function void print_value();
$display("Value: %0d", my_value);
endfunction
endclass
MyClass obj = new(); // 创建 MyClass 类的实例
// 使用 '.' 来访问成员
obj.print_value(); // 调用实例方法
$display("Value: %0d", obj.my_value); // 访问实例成员
obj.print_value():通过obj实例调用print_value方法。obj.my_value:访问obj实例的成员变量my_value。
3. this(当前实例)
在 SystemVerilog 中,this 关键字表示当前对象的 实例,即当前类的实例。当你在类的方法或构造函数中使用 this 时,它引用的是当前对象自身。
用途:
- 访问当前实例的成员。
- 用于传递当前对象的引用。
示例:
class MyClass;
int my_value;
function new(int value);
this.my_value = value; // 使用 this 来访问当前实例的成员
endfunction
function void print_value();
$display("Value: %0d", this.my_value); // 使用 this 来访问当前实例的成员
endfunction
endclass
MyClass obj = new(5);
obj.print_value(); // 输出: Value: 5
this.my_value:访问当前对象的成员my_value。this通常用于 构造函数 或 方法 中,特别是当你需要区分 实例成员 和 局部变量 时,this非常有用。
4. super(父类调用)
super 是 SystemVerilog 中用于调用 父类 的方法、构造函数等的关键字。它可以用来访问父类的成员或方法,特别是在类继承的上下文中。
用途:
- 调用父类的构造函数。
- 调用父类的方法或任务。
示例:
class ParentClass;
function new();
$display("Parent class constructor");
endfunction
function void display_message();
$display("Message from parent class");
endfunction
endclass
class ChildClass extends ParentClass;
function new();
super.new(); // 调用父类的构造函数
$display("Child class constructor");
endfunction
function void display_message();
super.display_message(); // 调用父类的 display_message 方法
$display("Message from child class");
endfunction
endclass
ChildClass child = new(); // 创建 ChildClass 的实例
child.display_message(); // 调用 display_message 方法
super.new():调用父类ParentClass的构造函数。super.display_message():调用父类的display_message方法。
5. 总结:
:::用于访问类的 静态成员 或 调用静态方法,也用于 UVM 工厂方法 的调用(如type_id::create)。.:用于访问类、模块或接口的 实例成员(变量、方法、任务等)。this:表示当前对象的实例,用于访问当前对象的成员或传递当前对象的引用。super:用于 调用父类的构造函数 或 方法,通常在类继承中使用。
这些语法符号和关键字是 SystemVerilog 和 面向对象编程(OOP) 中常用的基础工具,帮助你更好地组织和管理代码,特别是在验证和仿真中使用类、组件等结构时。

浙公网安备 33010602011771号