VMM scenario generators and dependent scenarios
Posted by Avinash Agrawal on 4th December 2009

Avinash Agrawal, Corporate Applications, Synopsys
Often folks wonder if it possible to have a VMM scenario generator, where one scenario is dependent on another scenario.
The answer is “Yes.”
Consider the testcase below. You can define two scenarios, scn_a and scn_b, both of which have their own set of constraints. The variables generated in scn_b are a multiple of the values that were set when scn_a was generated previously, in this case by variable “ratio”. For more details on how VMM scenario generators work, refer to the VMM user guide.
Systemverilog testcase:
——————————————————————————–
class packet extends vmm_data;
rand int sa;
rand int da;
`vmm_data_member_begin(packet)
`vmm_data_member_scalar(sa, DO_ALL)
`vmm_data_member_scalar(da, DO_ALL)
`vmm_data_member_end(packet)
endclass
`vmm_channel(packet)
`vmm_scenario_gen(packet, “packet”)
class a_scenario extends packet_scenario;
int unsigned scn_a;
rand int ratio;
function new();
scn_a = define_scenario(“scn_a”, 5);
endfunction
constraint cst_a {
$void(scenario_kind) == scn_a -> {
foreach(items[i]) {
this.items[i].sa inside {[0:100]};
this.items[i].da inside {[0:100]};
}
ratio inside {[1:5]};
}
}
endclass
class b_scenario extends packet_scenario;
int unsigned scn_b;
function new();
scn_b = define_scenario(“scn_b”, 10);
endfunction
constraint cst_b {
$void(scenario_kind) == scn_b -> {
foreach(items[i]) {
this.items[i].sa inside {[100:300]};
this.items[i].da inside {[100:300]};
}
}
}
endclass
class hier_scenario extends packet_scenario;
rand a_scenario scn_a;
rand b_scenario scn_b;
function new();
this.scn_a = new();
this.scn_b = new();
this.scn_a.set_parent_scenario(this);
this.scn_b.set_parent_scenario(this);
endfunction
virtual task apply(packet_channel channel, ref int unsigned n_insts);
this.scn_a.apply(channel, n_insts);
this.scn_b.apply(channel, n_insts);
endtask
constraint cst_hier {
foreach(scn_b.items[i]) {
// Create a scenario ‘scn_b’ depending upon ‘scn_a’
scn_b.items[i].sa inside {[scn_a.ratio*100:scn_a.ratio*800]};
scn_b.items[i].da inside {[scn_a.ratio*100:scn_a.ratio*800]};
}
}
endclass
program automatic test;
packet_scenario_gen scn_gen;
packet_channel pkt_chan;
packet pkt;
hier_scenario scn_hier;
initial begin
scn_hier = new();
scn_gen = new(“scn_gen”, -1, pkt_chan);
scn_gen.register_scenario(“scn_hier”, scn_hier);
scn_gen.unregister_scenario_by_name(“Atomic”);
$display(“Size of the scn is %0d”, scn_gen.scenario_set.size());
scn_gen.stop_after_n_insts = 15;
scn_gen.start_xactor();
while(1) begin
#10 scn_gen.out_chan.get(pkt);
$display(“id is %0d , %0d %0d”, pkt.data_id, pkt.sa, pkt.da);
end
end
endprogram
——————————————————————————–
Posted in Reuse, Stimulus Generation, Support, VMM | No Comments »