Some quick thoughts:-
1. use $dimensions
2. void'(obj.randomize())
if(!obj.randomize()) //preferred method
Try to avoid using assertions for checking randomization
3. use $urandom_range() in place of array index
4. use $urandom_range() with randc
5. Randomization fail when the constraints conflict , so i would first analysis the constraints that are conflicting
6. This can be done easily in UVM using get_name() or get_type_name() , which would return the string passed to new. To access using object in C++ one can use standard library
std::cout<<typeid(obj).name(). Not sure if this supports in SV.
7. If you assign an obj to other only the handles will be copied , so deep copy needs to be implemented
8.Is the question correct ? The program block is used to avoid race condition b/t the Tb and DUT since program block executes in reactive region whereas module executes in active region .
class C;
int q[$];
randc int index;
constraint select { index inside {[0:queue.size()-1]}; }
Tool specific solver debugging features
$typename(handle)
7. Deep-copy versus shallow copy
8. Race conditions between DUT to TB, DUT to DUT, TB to TB, can all be avoided with non-blocking assigments, and other basic synchronizing mechanisms like clocking blocks. Do not use program blocks.