在模块内部和模块外部声明类句柄的区别:

huangapple go评论53阅读模式
英文:

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”和类“变量”的区别。变量属于特定作用域,但句柄不属于任何特定作用域。句柄只是分配给变量的一个值,该值可以在不同的作用域之间传递。

case1case2之间的显著区别在于当有多个module xyz的实例时,case2为每个模块实例创建一个唯一的obj1变量和并发的initial块,构造与实例数量相同的对象。case1也有并发的initial块,但在$unit中只有一个obj1变量。因此,虽然两种情况都构造相同数量的对象句柄,但只有一个变量来保存一个句柄。它选择哪一个是一个竞争条件。

case3case2几乎相同,但根据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

huangapple
  • 本文由 发表于 2023年6月26日 22:01:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557406.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定