Systemverilog 作用域解析运算符 ::

Class scope resolution operator

Systemverilog作为面向对象的编程语言,很多特性参考Java,CPP。C++:作用域解析运算符 ::

作用域解析运算符Class scope resolution operator:: : 用于显式的对标识符identifier的命名空间namespace做出解析。

Systemverilog中的形式:class_type :: { class_type :: } identifier

常见归类如下:

  1. packet的使用,如import packets::*
  2. 内建类调用函数,如process::self;内建packet调用函数,如std::randomize()
  3. class endclass内部声明,外部定义function constraint,需要通过class_name::指定。
  4. 在class外部,对常量parameter localparam的引用。(parameter localparamelaboration-time赋值,construn-time赋值,常量constans为 read only)
  5. 对 静态变量static variable 静态方法static method 的调用
  6. 对静态成员static member的调用,如typedef创建新类型,enmu枚举变量
  7. 调用randomize with {}时使用local::identifier对重名的标识符做出区分
  8. 派生类内部访问父类的public变量和方法
  9. covergroup coverpoint cross的使用

Example

如下示例:

package SEASONS_PKG;
   typedef enum {SPRING,SUMMER,AUTUMN,WINTER} seasons_t;
endpackage

package TEST_PKG;

import SEASONS_PKG::*;

class SEED;
   rand int seed;
   constraint seed_value;
endclass

constraint SEED::seed_value {
   seed inside {[0:100]};
}

//class Packet #(localparam NAME = "DEFAULT_PKT"); // not work
class Packet #(parameter NAME = "DEFAULT_PKT");

   localparam NUMBER = 100;
   localparam WIDTH  = 32;

   static string id;

   enum {RED,BLUE,GREEN} COLOR_e;

   typedef bit [15:0] b16;

   const int seed;

   bit [WIDTH-1:0] value = 1;

   struct packed {
      bit [31:16] head;
      bit [15: 0] data;
   } frame_s;

   SEED m_seed;

   function new();
      seed = 100;
      m_seed = new();
      void'(std::randomize(frame_s) with {frame_s.head inside{1,3,5};frame_s.data inside {2,4,6};});
   endfunction

   extern static function void show_id();
   extern function int get_seed();
   extern function bit [WIDTH-1:0] get_value(); 
endclass

static function void Packet::show_id();
   $display("class Packet ID:%s",id);
endfunction

function int Packet::get_seed();
   void'(m_seed.randomize() with {seed == local::seed;});
   return m_seed.seed;
endfunction

function bit [Packet::WIDTH-1:0] Packet::get_value();
	return value;
endfunction

class Packet_e extends Packet;

   static function void get_number();
      $display("Packet number:%0d",Packet::NUMBER);
   endfunction

   function void get_value();
      //$display("Packet value:%0d",value);
      $display("Packet value:%0d",Packet::value);
   endfunction

   function void get_seed();
      //$display("Packet_e seed:%0d",get_seed());
      $display("Packet_e seed:%0d",Packet::get_seed());
   endfunction
endclass 

endpackage

module test();

   import TEST_PKG::*;

   Packet#("DATA_PKT") pkt;

   initial begin

      Packet#()::id = "PKT_1";
      Packet#()::show_id(); // class Packet ID:PKT_1
      Packet#("DATA_PKT")::show_id(); // class Packet ID:

      pkt = new();

      $display("frame_s : %p",pkt.frame_s); // frame_s : '{head:'h3, data:'h6}

      $display("name:%s",pkt.NAME); // name:DATA_PKT

      $display("name:%s",Packet#("CTRL_PKT")::NAME); // name:CTRL_PKT

      $display("number:%0d",Packet#()::NUMBER); // number:100

      $display("COLOR_e:%s",Packet#()::GREEN); // COLOR_e:GREEN

      $display("seed:%0d",pkt.get_seed()); // seed:100

	  $display("value:%0d",pkt.get_value()); // value:1
   end

   initial begin
      SEASONS_PKG::seasons_t seasons_e;
      #1ns;
      $display("seasons_e:%s",seasons_e.name()); // seasons_e:SPRING
      seasons_e = SEASONS_PKG::WINTER;
      $display("seasons_e:%s",seasons_e.name()); // seasons_e:WINTER
   end

   initial begin
      Packet#()::b16 val = 16'hABCD;
      #2ns;
      $display("val:%0h,type:%s,bits:%0d",val,$typename(val),$bits(val)); // val:abcd,type:bit[15:0],bits:16
   end

   initial begin
      Packet_e pkt_e;
      #3ns;
      Packet_e::get_number(); // Packet number:100
      pkt_e = new();
      pkt_e.get_value(); // Packet value:1
      pkt_e.get_seed(); // Packet_e seed:100
   end 

	process proc;
	initial begin
		proc = process::self();
		$display("process status:%s",proc.status()); // process status:RUNNING
	end
endmodule

Note

  • 参数化的类

class Packet是一个参数化的类parameterized class,使用时需要调用#generic class 进行specialization获得一个concrete type的类 ,否则报warning。Packet#()使用default值。

每一个concrete type的类,内部的静态成员都是相互独立的。如上述示例的 line 94,打印为空。

  • localparam
    localparam相比parameter,只能用于class module内部。而parameter可以用于class module的参数化声明。

  • new()
    Systemverilog 作用域解析运算符 ::_第1张图片

你可能感兴趣的:(systemverilog,systemverilog)