ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SystemVerilog Static Variables & Functions

2020-02-25 12:41:24  阅读:283  来源: 互联网

标签:Functions addr ctr 静态 Variables static new Static data


每个类实例通常都具有其每个内部变量的副本。

class Packet;
  bit [15:0]   addr;
  bit [7:0]   data;
 
  function new (bit [15:0] ad, bit [7:0] d);
    addr = ad;
    data = d;
    $display ("addr=0x%0h data=0x%0h", addr, data);
  endfunction
endclass
 
module tb;
  initial begin
    Packet   p1, p2, p3;
    p1 = new (16'hdead, 8'h12);
    p2 = new (16'hface, 8'hab);
    p3 = new (16'hcafe, 8'hfc);
  end
endmodule


Simulation Log
ncsim> run
addr=0xdead data=0x12
addr=0xface data=0xab
addr=0xcafe data=0xfc
ncsim: *W,RNQUIE: Simulation is complete.

每个类对象p1,p2,p3都将具有addr和data变量。

静态变量Static Variables

当类中的变量声明为静态时,该变量将是所有类实例中的唯一副本。 为了演示一个示例,我们将比较静态计数器与非静态计数器。 静态计数器使用static关键字声明,并命名为static_ctr,而普通计数器变量命名为ctr。 这两个计数器将在new()函数中递增,以便每次创建对象时更新它们。

class Packet;
  bit [15:0]   addr;
  bit [7:0]   data;
  static int   static_ctr = 0;
       int   ctr = 0;
 
  function new (bit [15:0] ad, bit [7:0] d);
    addr = ad;
    data = d;
    static_ctr++;
    ctr++;
    $display ("static_ctr=%0d ctr=%0d addr=0x%0h data=0x%0h", static_ctr, ctr, addr, data);
  endfunction
endclass
 
module tb;
  initial begin
    Packet   p1, p2, p3;
    p1 = new (16'hdead, 8'h12);
    p2 = new (16'hface, 8'hab);
    p3 = new (16'hcafe, 8'hfc);
  end
endmodule

您会看到静态计数器在所有类对象p1,p2和p3之间共享,因此当创建三个数据包时它将增加到3。 另一方面,普通计数器变量ctr没有声明为静态,因此每个类对象都有其自己的副本。 这就是为什么在创建所有三个对象后ctr仍为1的原因。

Simulation Log
ncsim> run
static_ctr=1 ctr=1 addr=0xdead data=0x12
static_ctr=2 ctr=1 addr=0xface data=0xab
static_ctr=3 ctr=1 addr=0xcafe data=0xfc
ncsim: *W,RNQUIE: Simulation is complete.

想要知道直到特定时间之前生成的数据包总数的情况下,将变量声明为静态变量可能非常有用。

静态功能

静态方法遵循所有类作用域和访问规则,但是唯一的区别是,即使没有类实例化,也可以在类外部调用它。 静态方法无法访问非静态成员,但可以直接访问静态类的属性或调用同一类的静态方法。 静态方法也不能是虚拟的。 使用类名称的静态函数调用需要通过作用域运算符::进行。

class Packet;
  static int ctr=0;
 
   function new ();
      ctr++;
   endfunction
 
  static function get_pkt_ctr ();
    $display ("ctr=%0d", ctr);
  endfunction
 
endclass
 
module tb;
  Packet pkt [6];
  initial begin
    for (int i = 0; i < $size(pkt); i++) begin
      pkt[i] = new;
    end
    Packet::get_pkt_ctr();   // 使用::操作符进行静态调用
    pkt[5].get_pkt_ctr();   // Normal call using instance
  end
endmodule
 
Simulation Log
ncsim> run
ctr=6
ctr=6
ncsim: *W,RNQUIE: Simulation is complete.

让我们添加一个名为mode的非静态成员,并尝试从我们的静态函数中调用它。

class Packet;
  static int ctr=0;
   bit [1:0] mode;
 
   function new ();
      ctr++;
   endfunction
 
  static function get_pkt_ctr ();
    $display ("ctr=%0d mode=%0d", ctr, mode);
  endfunction
endclass

不允许这样做,将导致编译错误。

      $display ("ctr=%0d mode=%0d", ctr, mode);
                                                      |
ncvlog: *E,CLSNSU (static-function.sv,10|40): A static class method cannot access non static class members.

参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-static-variables-functions

菜鸟-求指导 发布了105 篇原创文章 · 获赞 7 · 访问量 5621 私信 关注

标签:Functions,addr,ctr,静态,Variables,static,new,Static,data
来源: https://blog.csdn.net/qq_43042339/article/details/104494900

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有