The problem is you overrode the c_addr_default constraint in your derived class (BTW, see this post about the improper use of the work “child”), but when you that constraint off, the base c_addr_default remains active.
SystemVerilog does not give you an easy way to turn off both constraints. You need to provide a method in the base class to do it, or you need to assign seq to a base variable type, and access the constraint_mode from the base class variable.
An easier way to do this is provide another variable that holds the default addr value, and override the value prior to calling randomize.
class Base_seq xtends uvm_seq;
rand bit[31:0] addr;
bit [31:0] addr_default = 0;
constraint c_addr_default {
addr == addr_default;
}
enclass
class derived_seq xtends Base_seq;
function new();
super.new();
addr_default = 32'h0000_000F;
endclass
class test xtends Base_Test
derived_seq seq;
virtual task run_phase(uvm_run_phase);
super.run_phase(phase);
seq = derived_seq::type_id::create("seq");
..
seq.addr_default = 32'h 0000_FFFF;
if(!seq.randomize();
begin
`uvm_fatal("Randomization Failure")
end
endtask
If I write the base and extended class constraint as soft and use constraint_mode(0) using extended class object . So during the in-line constraint [ of test , could be hard or soft ]
my randomization would be successful .
Would that work as well ( Does this have any shortcoming ) ?
Yes, a soft constraint here would work. The reason I avoid promoting soft constraints is when you start getting into more complicated constraints, it becomes very difficult to follow when a soft constraint gets overridden or remains.
In reply to DoDo_Drx:
The problem is you overrode the c_addr_default constraint in your derived class (BTW, see this post about the improper use of the work “child”), but when you that constraint off, the base c_addr_default remains active.
SystemVerilog does not give you an easy way to turn off both constraints. You need to provide a method in the base class to do it, or you need to assign seq to a base variable type, and access the constraint_mode from the base class variable.
An easier way to do this is provide another variable that holds the default addr value, and override the value prior to calling randomize.
class Base_seq xtends uvm_seq;
rand bit[31:0] addr;
bit [31:0] addr_default = 0;
constraint c_addr_default {
addr == addr_default;
}
enclass
class derived_seq xtends Base_seq;
function new();
super.new();
addr_default = 32'h0000_000F;
endclass
class test xtends Base_Test
derived_seq seq;
virtual task run_phase(uvm_run_phase);
super.run_phase(phase);
seq = derived_seq::type_id::create("seq");
..
seq.addr_default = 32'h 0000_FFFF;
if(!seq.randomize();
begin
`uvm_fatal("Randomization Failure")
end
endtask
Hi Dave :
In below modified test case, i see both parent and child’s constraint got turned off. Maybe i am missing something.
Thanks
class base;
rand bit[31:0] addr;
constraint c_addr_default { addr == 32'h0; }
endclass
class child extends base;
constraint c_addr_default { addr == 32'h0000_000F; }
endclass
module test;
child c;
initial begin
c = new();
c.c_addr_default.constraint_mode(0);
c.randomize();
//c.randomize() with { addr == 32'h 0000_FFFF; };
$display(" c.addr is %0h", c.addr);
end
endmodule
// After statement c.c_addr_default.constraint_mode(0);
b = c ; // b is a Simple Base class Handle
if ( b.c_addr_default.constraint_mode() )
$display("Base Constraint is On"); // Outputs this i.e Base Class Constraint is ON
I observe the same results although on randomizing Extended Class Object
( addr is Non-Zero ) .