IMPORTANT NOTICE: Please be advised that the Verification Academy Forums will be offline for scheduled maintenance on Sunday, April 6th at 2:00 US/Pacific.
In example 1 and example 2, does creating object ‘gen_h’ and ‘drv_h’ have any difference? Is there any drawback in creating objects in a task rather than in function ‘new’ constructor? Thank you.
EXAMPLE 1:
class env;
generator gen_h; // here generator is a different class
driver drv_h; // here driver is a different class
function new();
gen_h = new();
drv_h = new();
endfunction
task run();
fork
gen_h.run();
drv_h.run();
join
endtask
endclass
EXAMPLE 2:
class env;
generator gen_h; // generator is a different class
driver drv_h; // driver is a different class
task run();
gen_h = new();
drv_h = new();
fork
gen_h.run();
drv_h.run();
join
endtask
endclass
Your question really should be: “what code should we put in the constructor versus any other class method?”
There are at least two independent issues. One is when you extend a class, you cannot override the constructor, you can only append to it. So you can’t prevent the driver from being constructed. You should put the bare minimum amount of code in a class constructor.
The other issuer is getting the randomization seed to each object. You didn’t show the code for how the env classes get constructed and the run method gets called, but I’m assuming you are using OVM/UVM or something similar. The run phases of these classes all get forked in parallel, so your chances of random stability are diminished when using the run phase.