System verilog SystemVerilog vs C++;作业:参考还是复印? 我主要有C++背景。我正在跟踪我正在处理的SystemVerilog代码中的一个bug,并惊讶地发现我认为是对象复制分配实际上是一个引用分配。此简化代码显示了我的意思: for (int i = 0; i < max_num; ++i) { var cls_obj obj1; obj1 = obj_array[i]; some_function(obj1); // modifies the object passed in // at this point BOTH obj1 and obj_array[i] are modified. // some other code goes here } for(int i=0;i我也注意到这个问题,当我学习C++和SV时,实际上,所有的SV属性都在LRM中被详细描述(最新版本是IEEE-1800—2017)。这个问题在第8.2章和第13.5章中陈述:

System verilog SystemVerilog vs C++;作业:参考还是复印? 我主要有C++背景。我正在跟踪我正在处理的SystemVerilog代码中的一个bug,并惊讶地发现我认为是对象复制分配实际上是一个引用分配。此简化代码显示了我的意思: for (int i = 0; i < max_num; ++i) { var cls_obj obj1; obj1 = obj_array[i]; some_function(obj1); // modifies the object passed in // at this point BOTH obj1 and obj_array[i] are modified. // some other code goes here } for(int i=0;i我也注意到这个问题,当我学习C++和SV时,实际上,所有的SV属性都在LRM中被详细描述(最新版本是IEEE-1800—2017)。这个问题在第8.2章和第13.5章中陈述:,system-verilog,System Verilog,我只希望修改obj1。这是因为var关键字吗?复制分配与参考分配在SystemVerilog中究竟是如何工作的?我很难从web搜索中找到信息。SystemVerilog中的类变量是引用或句柄。仅当您使用new关键字时,才会创建实例 因此,在您的示例中,obj1和obj_数组[i]都引用(或指向)同一实例 默认情况下,SystemVerilog中的函数参数按值传递。然而,类句柄被视为值,所以传递到函数中的任何类都有效地通过引用传递 在初始化类对象时,该语言中有一种内置机制来执行浅层复制 Packe

我只希望修改
obj1
。这是因为var关键字吗?复制分配与参考分配在SystemVerilog中究竟是如何工作的?我很难从web搜索中找到信息。

SystemVerilog中的类变量是引用或句柄。仅当您使用
new
关键字时,才会创建实例

因此,在您的示例中,
obj1
obj_数组[i]
都引用(或指向)同一实例

默认情况下,SystemVerilog中的函数参数按值传递。然而,类句柄被视为值,所以传递到函数中的任何类都有效地通过引用传递

在初始化类对象时,该语言中有一种内置机制来执行浅层复制

Packet p1;
Packet p2;
p1 = new;
p2 = new p1;
这是一个肤浅的副本。对于对象,仅复制控制柄

IEEE 1800-2009第8.11章举例说明了这一点


var
关键字与您看到的行为没有任何关系。事实上,我甚至从未见过或使用过
var
。根据LRM,这允许在声明变量时省略类型。在你的代码中,指定了类型(CLSYOBJ),所以我不认为它的存在是在做任何事情。

< P>我也注意到这个问题,当我学习C++和SV时,实际上,所有的SV属性都在LRM中被详细描述(最新版本是IEEE-1800—2017)。这个问题在第8.2章和第13.5章中陈述:

第13.5章:关于子程序

SystemVerilog提供了两种向任务和函数传递参数的方法:按值和按引用。 参数也可以通过名称和位置进行绑定。也可以给出子例程参数 默认值,允许对子例程的调用不传递参数

总之:
默认情况下,子例程(包括函数和任务)参数按值传递,并且仅在添加ref关键字时按引用传递。

第8.2章:关于类和对象

面向对象的类扩展允许动态创建和销毁对象。类实例, 或对象,可以通过对象句柄传递,这提供了安全的指针功能。物体可以 被声明为带有方向输入、输出、inout或ref的参数。在每种情况下,参数 复制的是对象句柄,而不是对象的内容

总之:
对象是类的实例,对象的名称是它的引用或句柄,而不是它本身,这类似于c++中的指针(按类型*ptrname声明)或引用(delcare by:type&refname)。因此,无论何时生成对象,都要操纵它的句柄。因此,当您在不使用ref关键字althrough的情况下将对象传递给子例程时,它将按值传递,但值(对象名称)是对象的句柄,而不是对象本身。因此,无论是否添加ref关键字,类都将按引用传递

此外,这就是为什么SV中的新商业广告会出现一个非常常见的错误,即流动(来自):

错误是:只创建一个instance类事务,因此在邮箱mbx中,10对象指向单个相同的实例。正确的方法是在需要对象时创建多个对象,换句话说,将“t=new()”放在循环块中

> task generate_transaction()
Transaction t;
mailbox mbx;
repeat(10) begin
    **t = new(); // right place**
    assert(t.randomize());
    mbx.put(t);
end

您是否有权访问IEEE 1800-2009 LRM?这在第8.11章中解释得很清楚。嘿,温克尔,其实我不知道。我在网上找到的,但要花钱。我可能需要和我的同事核实一下,看看我们是否有。谢谢你让我知道。仅供参考,2012版LRM现在可以在线免费下载:太好了,谢谢!在这方面,VAR看起来更像java,而不是C++。Var表示“这是一个变量声明”。它几乎总是可以省略的,因为它是隐含的。也有例外,但它们是模糊的。我只使用过一次“var”。Dave在验证学院[link1]()中也解释了这一点,
> task generate_transaction()
Transaction t;
mailbox mbx;
repeat(10) begin
    **t = new(); // right place**
    assert(t.randomize());
    mbx.put(t);
end