Saturday, 30 April 2016

Singleton class in System Verilog

Sometimes it is required to have only one object of some classes like configuration classes. For this purpose we create singleton classes.
Only one object is created for a singleton class and whenever we try to create a new object, same object is returned.

System verilog does not provide construct to create a singleton class. But we can create it with some manipulation.

---------------------------------------------------------------------
class singleton;
int unsigned var1;
// Need to declare it as static,
// as it is accessed by static method 'create'
static singleton single;
// Declared as 'protected',
// so user can't directly create instance of this class
protected function new();
endfunction : new
// Make it static,
// so user can use it before class is constructed
// To create instance of this class first time when this it is not create
static function singleton create();
if (single == null) begin
$display("Object single is null, so creating new object");
single = new();
end
return single;
endfunction : create
endclass : singleton
module top();
singleton s1, s2;
initial begin
// create is static method so we can use it directly
// using <class_name :: method_name>
s1 = singleton :: create();
$display (" 1 : s1.var1 = %0d", s1.var1);
s1.var1 = 10;
$display (" 2 : s1.var1 = %0d", s1.var1);
s2 = singleton :: create();
$display (" 3 : s2.var1 = %0d", s2.var1);
s2.var1 = 20;
$display (" 4 : s2.var1 = %0d", s2.var1);
$display (" 5 : s1.var1 = %0d", s1.var1);
end
endmodule : top
//Output:
// Object single is null, so creating new object
// 1 : s1.var1 = 0
// 2 : s1.var1 = 10
// 3 : s2.var1 = 10
// 4 : s2.var1 = 20
// 5 : s1.var1 = 20
view raw singleton.sv hosted with ❤ by GitHub

---------------------------------------------------------------------


uvm_root class defined as a singleton class in UVM source code.
---------------------------------------------------------------------
// Snippet of UVM souce code for singleton
virtual class uvm_coreservice_t;
local static `UVM_CORESERVICE_TYPE inst;
static function uvm_coreservice_t get();
if(inst==null)
inst=new;
return inst;
endfunction // get
pure virtual function uvm_root get_root();
endclass
class uvm_default_coreservice_t extends uvm_coreservice_t;
pure virtual function uvm_root get_root();
virtual function uvm_root get_root();
return uvm_root::m_uvm_get_root();
endfunction
endclass
class uvm_root extends uvm_component;
// singleton handle
static local uvm_root m_inst;
extern protected function new ();
function uvm_root::new();
super.new("__top__", null);
m_rh.set_name("reporter");
clp = uvm_cmdline_processor::get_inst();
report_header();
// This sets up the global verbosity. Other command line args may
// change individual component verbosity.
m_check_verbosity();
endfunction
// internal function not to be used
// get the initialized singleton instance of uvm_root
static function uvm_root m_uvm_get_root();
if (m_inst == null) begin
m_inst = new();
void'(uvm_domain::get_common_domain());
m_inst.m_domain = uvm_domain::get_uvm_domain();
end
return m_inst;
endfunction
uvm_coreservice_t cs;
extern static function uvm_root get();
function uvm_root uvm_root::get();
uvm_coreservice_t cs = uvm_coreservice_t::get();
return cs.get_root();
endfunction
endclass

---------------------------------------------------------------------

4 comments: