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

Viewed 43

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?

2 Answers

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

and without classes

int  count = 0;
module Singleton();
  initial begin
      if (count != 0) 
        $error("Multiple instances of %m");
      count ++;
    end
endmodule

module BAD_Design();
  Singleton singleton1();
  Singleton singleton2();
endmodule
Related