英文:
systemverilog: difference between declaring class handle inside module and outside module
问题
案例 1:
class abc;
...
..
endclass
abc obj1; // 在模块外声明
module xyz();
initial
obj1 = new; // 创建对象
endmodule
案例 2:
class abc;
...
..
endclass
module xyz();
abc obj1; // 在模块内声明
initial
obj1 = new; // 创建对象
endmodule
案例 3:
class abc;
...
..
endclass
module xyz();
initial
abc obj1 = new; // 声明并创建对象
endmodule
英文:
i want to understand the difference between creating class handle outside and inside module. I have 3 cases and i want to understand the significance of each
case 1:
class abc;
...
..
endclass
abc obj1; //declaration outside module
module xyz();
initial
obj1=new; //creating object
endmodule
case 2:
class abc;
...
..
endclass
module xyz();
abc obj1; //declaration inside module
initial
obj1=new; //creating object
endmodule
case 3
class abc;
...
..
endclass
module xyz();
initial
abc obj1=new; //declaring and creating object
endmodule
答案1
得分: 2
模块外部的作用域称为“编译单元”,并称为$unit
。最小情况下,它包括单个文本文件中模块外部的所有空间。最大情况下,它可以包括单个编译步骤中模块外部的所有文本。无法在不同的编译单元之间共享定义。类定义通常放在package
中,以便在不同的单元之间共享。
还要注意类“handle”和类“变量”的区别。变量属于特定作用域,但句柄不属于任何特定作用域。句柄只是分配给变量的一个值,该值可以在不同的作用域之间传递。
case1和case2之间的显著区别在于当有多个module xyz
的实例时,case2为每个模块实例创建一个唯一的obj1
变量和并发的initial
块,构造与实例数量相同的对象。case1也有并发的initial
块,但在$unit
中只有一个obj1
变量。因此,虽然两种情况都构造相同数量的对象句柄,但只有一个变量来保存一个句柄。它选择哪一个是一个竞争条件。
case3与case2几乎相同,但根据LRM的规定是非法的。不允许在隐式静态变量上进行声明初始化,这些变量本可以使用显式的自动生命周期声明。这是因为传统的Verilog默认将所有声明都具有静态生命周期,而大多数其他编程语言默认具有自动生命周期。当声明初始化位于循环结构内部时,问题会最明显地显现出来。
要修复这个问题,您需要编写:
initial
static abc obj1=new; //声明和创建对象
或者
initial begin
abc obj1; //声明和
obj1=new; // 创建对象
end
英文:
The scope outside a module is called a compilation unit and referred to as $unit
. At a minimum, it includes all the space outside a module within a single text file. At a maximum, it can include all the text outside a module in a single compilation step. There is no way to share definitions across separate compilation units. Class definitions are typically put in a package
so they can be shared across different units.
Also note the difference between a class handle and a class variable. A variable belongs to a particular scope, but a handle does not. A handle is just a value that gets assigned to a variable and that value can be passed between scopes.
The significant difference between case1 and case2 is when there are multiple instances of module xyz
case2 creates a unique obj1
variable and concurrent initial
block for each instance of the module that constructs as many objects as there are instances. case1 also has the concurrent initial
blocks, but only one obj1
variable in $unit
. So although both cases construct the same number of object handles, There is only one variable to hold one handle. Which one it chooses is a race condition.
case3 is almost the same as case2, but is illegal according to the LRM. You are not allowed to have a declaration initialization on implicitly static variable that could have been declared with an explicit automatic lifetime. This is because of legacy Verilog's choice of making all declarations having a static lifetime by default, whereas most other programming languages default to having an automatic lifetime. The problem shows up best when the declaration initialization is inside a looping construct.
To fix this you would have to write
initial
static abc obj1=new; //declaring and creating object
or
initial being
abc obj1; //declaring and
obj1=new; // creating object
end
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论