Hi forum colleges.
This thread helped me allot in understanding what exactly is ordering constraint.
I wrote a code that summarize all the above discussions.
If its appropriate I want to put it here so other readers can copy it and test it in their machines.
example 1 is bmorris original question
example 2 is dave example where for each enum value there may be different number of inst values
Here are the results of simulation
For set object, number of SET1=986, SET2=1008, SET3=1006 WITHOUT_ORDERING
For set object, number of SET1=988, SET2=1000, SET3=1012 WITH_ORDERING
For feel object, number of BAD=516, GOOD=832, NONE=1652 WITHOUT_ORDERING
For feel object, number of BAD=1023, GOOD=1014, NONE=963 WITH_ORDERING
package tb_env;
import uvm_pkg::*;
`include "uvm_macros.svh"
typedef enum bit [3:0] { SET1, SET2, SET3 } e_sets ;
typedef enum bit [7:0] { FLEE=0, JUMP=1, FLY=2 } e_set1_instructions ;
typedef enum bit [7:0] { GROW=34, SLEEP=35, AWAKEN=36 } e_set2_instructions ;
typedef enum bit [7:0] { RUSH=114, STARE=115, WAIT=116 } e_set3_instructions ;
typedef enum bit [3:0] { BAD, GOOD, NONE } e_feel ;
typedef enum bit [7:0] { SAD=0, GRIEF=1, UNHAPPY=2 } e_feel_bad ;
typedef enum bit [7:0] { SMILE=34, JOY=35, HAPPY=36, EXITED=37, LAUGH=38} e_feel_good ;
typedef enum bit [7:0] { APATHETIC=114, LETHARGIC=115, INDIFFERENT=116, POCOCURANT=117, SLUGGISH=118,
INERT=119, IMPASSIVE=120, PHLEGMATIC=121, LACKADAISICAL=122, NEUTRAL=123} e_feel_none ;
typedef enum bit {WITHOUT_ORDERING=0, WITH_ORDERING=1} e_order;
class infra;
static function void print_pair(input bit is_display, input string str1, str2);
if (is_display) $display("{%s, %s}",str1, str2);
endfunction
endclass
class sets extends uvm_object;
rand e_sets set;
rand bit [7:0] inst;
e_set1_instructions set1;
e_set2_instructions set2;
e_set3_instructions set3;
static int num_of_SET1;
static int num_of_SET2;
static int num_of_SET3;
bit is_display=1'b0;
constraint set_c
{
(set == SET1) -> inst inside {[0:2]};
(set == SET2) -> inst inside {[34:36]};
(set == SET3) -> inst inside {[114:116]};
}
constraint order {solve set before inst;}
`uvm_object_utils(sets)
function new (string name = "sets");
super.new(name);
endfunction
function void post_randomize();
if (set==SET1) begin
set1=e_set1_instructions'(inst);
num_of_SET1++;
infra::print_pair(is_display, set.name(), set1.name());
end
else if (set==SET2) begin
set2=e_set2_instructions'(inst);
num_of_SET2++;
infra::print_pair(is_display, set.name(), set1.name());
end
else if (set==SET3) begin
set3=e_set3_instructions'(inst);
num_of_SET3++;
infra::print_pair(is_display, set.name(), set1.name());
end
endfunction
static function void clear_static();
num_of_SET1=0; num_of_SET2=0; num_of_SET3=0;
endfunction
endclass
class feels extends uvm_object;
rand e_feel feel;
rand bit [7:0] inst;
e_feel_bad feel_bad;
e_feel_good feel_good;
e_feel_none feel_none;
static int num_of_feel_bad;
static int num_of_feel_good;
static int num_of_feel_none;
bit is_display=1'b0;
constraint c_feel
{
(feel==BAD) -> inst inside {[0:2]};
(feel==GOOD) -> inst inside {[34:38]};
(feel==NONE) -> inst inside {[114:123]};
}
constraint order {solve feel before inst;}
`uvm_object_utils(feels)
function new (string name = "feels");
super.new(name);
endfunction
function void post_randomize();
if (feel==BAD) begin
feel_bad=e_feel_bad'(inst);
num_of_feel_bad++;
infra::print_pair(is_display, feel.name(), feel_bad.name());
end
else if (feel==GOOD) begin
feel_good=e_feel_good'(inst);
num_of_feel_good++;
infra::print_pair(is_display, feel.name(), feel_good.name());
end
else if (feel==NONE) begin
feel_none=e_feel_none'(inst);
num_of_feel_none++;
infra::print_pair(is_display, feel.name(), feel_none.name());
end
endfunction
static function void clear_static();
num_of_feel_bad=0; num_of_feel_good=0; num_of_feel_none=0;
endfunction
endclass
class var_order_test extends uvm_test;
sets set;
feels feel;
`uvm_component_utils(var_order_test)
function new (string name, uvm_component parent);
super.new(name, parent);
endfunction
task run_phase (uvm_phase phase);
super.run_phase (phase);
// Run 2 iterations off 3000 randomization per iteration
// in iteration 1 disable the ordering constraint and enable in 2
// Static couters counts number of selection per enum value
for (int j=0; j<2; j++) begin
e_order e = e_order'(j);
for (int i=0; i<3*1000; i++) begin
set=sets::type_id::create("set");
set.is_display=1'b0;
set.order.constraint_mode(j);
if (!set.randomize()) `uvm_error(get_name(), "Failed to randomize sets object")
end
$display ("For set object, number of SET1=%0d, SET2=%0d, SET3=%0d %s",
set.num_of_SET1, set.num_of_SET2, set.num_of_SET3, e.name());
sets::clear_static();
end
for (int j=0; j<2; j++) begin
e_order e = e_order'(j);
for (int i=0; i<3*1000; i++) begin
feel=feels::type_id::create("feel");
feel.is_display=1'b0;
feel.order.constraint_mode(j);
if (!feel.randomize()) `uvm_error(get_name(), "Failed to randomize feel object")
end
$display ("For feel object, number of BAD=%0d, GOOD=%0d, NONE=%0d %s",
feel.num_of_feel_bad, feel.num_of_feel_good, feel.num_of_feel_none, e.name());
feels::clear_static();
end
endtask
endclass
endpackage : tb_env
module top;
import uvm_pkg::*;
`include "uvm_macros.svh"
import tb_env::*;
initial begin
run_test("var_order_test");
end
endmodule