Search code examples
verilogsystem-verilog

Simplest way to enforce that a module is only instanced once?


Suppose I have a (not synthesizable) simulation-only Verilog module.

How can I detect/enforce if it is elaborated more than once anywhere in a simulation?

module Singleton();
  // I only want one of these...
endmodule

module GOOD_Design();
  Singleton singleton();
endmodule

module BAD_Design();
  Singleton singleton1();
  Singleton singleton2();
endmodule
  • My best thought is to create a static variable in a package and do something like this:
package SingletonPkg();
  static bit once = 1'b0;
endpackage

module Singleton();
  initial begin: singleton
    if (SingletonPkg::once == 1'b1)
      $fatal(2);
    SingletonPkg::once = 1'b1;
  end
  ...
endmodule: Singleton

Seems a lot of work (and I still have to make the test/set into an atomic operation). I could use the same approach with a DPI function as well, and keep the bit in C instead of SV.

Nevertheless, is there a better/simpler way?


Solution

  • You can make it slightly simpler by using a class

    package SingletonPkg;
     class C;
      static bit once = 1'b0;
      function new;
         if (once++ != 0) $fatal(2);
      endfunction
     endclass
    endpackage
    
    module Singleton();
      SingletonPkg::C = new; 
      ...
    endmodule: Singleton